种豆资源网

当前位置:首页 > 百科 > 百科综合 / 正文

构造函式

(2020-02-16 13:37:46) 百科综合
构造函式

构造函式

构造函式 ,是一种特殊的方法。主要用来在创建对象时初始化对象, 即为对象成员变数赋初始值,总与new运算符一起使用在创建对象的语句中。特别的一个类可以有多个构造函式 ,可根据其参数个数的不同或参数类型的不同来区分它们 即构造函式的重载。

基本介绍

  • 中文名:构造函式
  • 外文名:constructor
  • 作用:为对象成员变数赋初始值
  • 语句:new运算符一起使用

主要特点

1.构造函式的命名必须和类名完全相同。在java中普通函式可以和构造函式同名,但是必须带有返回值;
2.构造函式的功能主要用于在类的对象创建时定义初始化的状态。它没有返回值,也不能用void来修饰。这就保证了它不仅什幺也不用自动返回,而且根本不能有任何选择。而其他方法都有返回值,即使是void返回值。儘管方法体本身不会自动返回什幺,但仍然可以让它返回一些东西,而这些东西可能是不安全的;
3.构造函式不能被直接调用,必须通过new运算符在创建对象时才会自动调用;而一般的方法是在程式执行到它的时候被调用的;
4.当定义一个类的时候,通常情况下都会显示该类的构造函式,并在函式中指定初始化的工作也可省略,不过Java编译器会提供一个默认的构造函式.此默认构造函式是不带参数的。而一般的方法不存在这一特点;
5.构造函式有回滚的效果,构造函式抛出异常时,构造的是一个不完整对象,会回滚,将此不完整对象的成员释放(c++)
6.当一个类只定义了私有的构造函式,将无法通过new关键字来创建其对象,当一个类没有定义任何构造函式,C#编译器会为其自动生成一个默认的无参的构造函式。
7.在Python中构造函式必须通过重写__init__方法实现

套用

C++构造函式
C++语言为类提供的构造函式可自动完成对象的初始化任务,全局对象和静态对象的构造函式在main()函式执行之前就被调用,局部静态对象的构造函式是当程式第一次执行到相应语句时才被调用。然而给出一个外部对象的引用性声明时,并不调用相应的构造函式,因为这个外部对象只是引用在其他地方声明的对象,并没有真正地创建一个对象。
C++的构造函式定义格式为:
class <类名>
{
public:
<类名>(参数表);
//...(还可以声明其它成员函式)
};
<类名>::<函式名>(参数表)
{
//函式体
}
如以下定义是合法的:
class T
{
public:
T(int a=0){ i=a; }//构造函式允许直接写在类定义内,也允许有参数表。
private:
int i;
};
如果一个类中没有定义任何的构造函式,那幺编译器只有在以下三种情况,才会提供默认的构造函式:
1、如果类有虚拟成员函式或者虚拟继承父类(即有虚拟基类)时;
2、如果类的基类有构造函式(可以是用户定义的构造函式,或编译器提供的默认构造函式);
3、在类中的所有非静态的对象数据成员,它们对应的类中有构造函式(可以是用户定义的构造函式,或编译器提供的默认构造函式)。
<类名>::<类名>(){},即不执行任何操作。
例子
#include <iostream>using namespace std;class time{public:    time()//constructor.构造函式    {        hour=0;        minute=0;        sec=0;    }    void set_time();    void show_time();private:    int hour, minute, sec;};int main(){    class time t1;    t1.show_time();    t1.set_time();    t1.show_time();    return 0;}void time::set_time(){    cin>>hour>>minute>>sec;}void time::show_time(){    cout<<hour<<":"<<minute<<":"<<sec<<endl;}
程式运行情况:
0:0:0
10 11 11 回车
10:11:11
任何时候,只要创建类或结构,就会调用它的构造函式。类或结构可能有多个接受不同参数的构造函式。构造函式使得程式设计师可设定默认值、限制实例化以及编写灵活且便于阅读的代码。
PHP的构造函式
void__construct( [mixed args [, ...]] )
php 5 允行开发者在一个类中定义一个方法作为构造函式。具有构造函式的类会在每次创建对象时先调用此方法,所以非常适合在使用对象之前做一些初始化工作。
注:如果子类中定义了构造函式则不会暗中调用其父类的构造函式。要执行父类的构造函式,需要在子类的构造函式中调用parent::__construct()
例子 使用新标準的构造函式
<?phpclassBaseClass{function__construct(){print"InBaseClassconstructor/n";}}classSubClassextendsBaseClass{function__construct(){parent::__construct();print"InSubClassconstructor/n";}}$obj=newBaseClass();$obj=newSubClass();?>
为了实现向后兼容性,如果 php 5 在类中找不到__construct()函式,它就会尝试寻找旧式的构造函式,也就是和类同名的函式。因此唯一会产生兼容性问题的情况是:类中已有一个名为__construct()的方法,但它却又不是构造函式。
Python的构造函式
定义格式为
class <类名>:
__init__(self [,参数表]):
#函式体
#其它的方法和属性

其他特点

1.它的函式名与类名相同;
2.它可以重载;
3.不能指定返回类型,即使是void也不行;
4.虽然在一般情况下,构造函式不被显式调用,而是在创建对象时自动被调用。但是并不是不能被显式调用。有些时候是一定要显式调用的,只要是父类有带参的构造函式,在子类中就必须显式的调用父类的构造函式,因为子类的构造器在实例化时无法找到父类的构造函式(当父类有自己写的无参构造函式时,子类也不用显式调用)。
void__destruct( void )
php 5 引入了析构函式的概念,这类似于其它面向对象的语言,如 C++。析构函式会在到某个对象的所有引。

语法

  • Java, C++, C#, ActionScript和PHP 4中的命名规範会要求构造器函式的名称与它所在类的名称相同。
  • PHP 5 建议的构造器函式名称为__construct。为了保证向下兼容,__construct方法无法找到时会调用任何跟类名同名的方法作为构造器。从 PHP 5.3.3 起,这种途径只对非名字空间的类有效。
  • 在Perl里,构造器被约定俗成地命名为"new",并且会完成创建对象的大量工作。
  • 在 Perl 的 Moose 对象系统中,构造函式(叫做 new)是自动生成的,程式设计师可以通过指定一个 BUILD 方法来对其进行扩充。
  • 在 Visual Basic .NET里,构造器被命名为New,是个 Sub。
  • Python里构造器的被分为 __new__ 和 __init__ 两个方法。__new__方法负责为实例分配内储存空间,并接受自身的类作为参数(一般命名为 cls)。__init__方法接受被新建的实例作为参数(一般称为 self)。
  • Object Pascal 的构造函式用关键字 constructor 标识,并且可以起任意名字(但一般来说会被起名为 Create)。
  • Objective-C 的构造函式分成两个方法,alloc 和 init。alloc 方法分配记忆体,init 负责初始化。new 方法会调用 alloc 和 init 两者。

记忆体机制

在 Java, C# 和 VB .NET 里,构造器会在一种叫做堆的特殊数据结构里创建作为引用类型的实例。值类型(例如 int, double 等等)则会创建在叫做栈的有序数据结构里。VB .NET and C# 会允许用new来创建值类型的实例。然而在这些语言里,即使使用这种方法创建的对象依然只会在栈里。
在 C++ 里,不用 new 创建的对象会保存在栈里,使用 new 创建时则会在堆里。它们必须分别使用析构函式或者delete操作才能被删除。

语言细节

Java

在Java里,构造器和其他方法的主要差别在于:
  • 构造器不具有任何显性返回类型。
  • 构造器无法被直接“new” invokes them).
  • 构造器无法被标示为synchronized, final, abstract, native, 或者static
Java 里的构造器会按照以下顺序完成下列工作:
  1. 将类变数初始到预设值。(byte, short, int, long, float, 和 double 变数会默认设为它们相应的0值,booleans 会被设为 false, chars 会被设为空字元('\u0000'),对象引用会被设为 null)
  2. 引用父类的构造器,如果没有定义任何构造器。
  3. 将实例变数初始化到指定值。
  4. 执行构造器内的代码。
在 Java 中可以通过关键字super访问父类的构造器。
public class Example{    // Definition of the constructor.    public Example()    {        this(1);    }    // Overloading a constructor    public Example(int input)    {        data = input; // This is an assignment    }    // Declaration of instance variable(s).    private int data;} 
// Code somewhere else// Instantiating an object with the above constructorExample e = new Example(42);
不接收任何参数的构造器被称作“无参数构造器”。

Visual Basic .NET

在Visual Basic .NET中, 构造函式以"New"为定义方法,并且必须是个 Sub。
Class Foobar    Private strData As String    ' Constructor    Public Sub New(ByVal someParam As String)        strData = someParam    End SubEnd Class
' code somewhere else' instantiating an object with the above constructorDim foo As New Foobar(".NET")

C#

public class MyClass{    private int a;    private string b;    // Constructor    public MyClass() : this(42, "string")    {    }    // Overloading a constructor    public MyClass(int a, string b)    {        this.a = a;        this.b = b;    }}
// Code somewhere// Instantiating an object with the constructor aboveMyClass c = new MyClass(42, "string");
C# 静态构造函式
在C#中,静态构造函式是用来初始化任何静态数据。静态构造函式也称为“类构造函式”,由于类构造函式在生成的 MSIL 里名为“.cctor”,因此也被称为“cctor”。
静态构造函式允许複杂的静态变数初始化。
静态构造函式在该类第一次被访问时调用,任何使用该类的操作(无论是调用静态函式、属性还是访问静态变数,还是构造类的实例)都会引发静态构造函式的执行。静态构造函式是执行绪安全的,并且是单例的。当用在泛型类中时,静态构造函式对于泛型的每个实例化都调用一次。静态变数也同样如此。
public class MyClass{    private static int _A;    // Normal constructor    static MyClass()    {        _A = 32;    }    // Standard default constructor    public MyClass()    {    }}// Code somewhere// Instantiating an object with the constructor above// right before the instantiation// The variable static constructor is executed and _A is 32MyClass c = new MyClass();

C++

C++ 的构造函式以该类的类名为标识,且不写返回值类型也无法返回值:
class C{public:  C(void){    ...  }};
构造函式的函式体执行是在各个成员构造完之后才开始,因此要想更改成员的构造方式需要使用成员初始化列表:
class D: public B{public:  D(void): B("Hello, world!"){    ...  }};
複製构造函式接受同类对象的左值引用(一般为 const T &)、移动构造函式接受右值引用(一般为 T&&):
class E{public:  E(const E &e){...}//Copy constructor  E(E &&e){...}//Move constructor};
C++ 中,程式设计师若未对某类定义构造函式(以及赋值函式、析构函式),编译器在满足条件时会定义相应的函式。

Ruby

irb(main):001:0> class ExampleClassirb(main):002:1>   def initializeirb(main):003:2>     puts "Hello there"irb(main):004:2>   endirb(main):005:1> end=> nilirb(main):006:0> ExampleClass.newHello there=> #<ExampleClass:0x007fb3f4299118>

标 签

搜索
随机推荐

Powered By 种豆资源网||