我希望了解编译器提供的构造函数的作用是什么?这个构造函数是否负责内存分配以及创建对象所需的所有内容。
我并不是从成员变量初始化的角度来问这个问题。我想知道默认构造函数在编译器执行和提供的过程中发生了什么。
我希望了解编译器提供的构造函数的作用是什么?这个构造函数是否负责内存分配以及创建对象所需的所有内容。
我并不是从成员变量初始化的角度来问这个问题。我想知道默认构造函数在编译器执行和提供的过程中发生了什么。
默认构造函数是指没有参数或者所有参数都有默认值的构造函数。
如果一个类A没有用户定义的构造函数并且需要一个构造函数,编译器会隐式声明一个默认无参构造函数 A::A()。这个构造函数是其类的内联公共成员。当编译器使用这个构造函数创建类型为A的对象时,编译器会隐式定义 A::A()。这个构造函数将没有构造函数初始化程序和空的主体。
在定义A的隐式声明构造函数之前,编译器首先定义A的基类和非静态数据成员的隐式声明构造函数。如果一个类A有任何常量或引用类型成员,则不会创建默认构造函数。
如果一个类A的构造函数满足以下条件,则它是平凡的:
* It is implicitly defined
* A has no virtual functions and no virtual base classes
* All the direct base classes of A have trivial constructors
* The classes of all the nonstatic data members of A have trivial constructors
一个默认构造函数。
它没有参数(或者所有参数都有默认值),因此可以构造一个没有任何参数的对象。
如果您没有定义任何构造函数,编译器将为您生成一个默认构造函数。
编译器生成的默认构造函数按以下顺序执行:
复制构造函数:
如果您没有定义复制构造函数,则编译器将生成一个默认的复制构造函数。
编译器生成的复制构造函数按以下顺序执行:
虽然不是构造函数。重要的是要注意,当未定义赋值运算符时,编译器还将自动生成赋值运算符。
编译器生成的赋值运算符按以下顺序执行:
默认析构函数:
大多数人认为析构函数是微不足道的或不存在的。但是需要注意默认版本实际上做了些什么(它比什么都没有稍微多一点)。
如果您定义了一个析构函数,则行为不会改变。但是,作为析构函数的一部分定义的代码在上述定义的行为之前执行。因此,在实际上始终存在析构函数,只是代码为空块。
注意:当使用虚拟基类时,有一些特殊考虑因素。但这是另一个问题。
因此,即使您定义了一个空类,编译器也将始终为您生成四个方法:
class X: public Z
{
int a;
Y b;
Z* c;
};
// Compiler generated methods will look like this:
X::X()
:Z() // Construct base class.
//,a?? The default construction of an int does nothing the value is undefined.
,b()
//,c?? The default construction of a pointer does nothing,
{}
X::~X()
{} // Note members are destoyed here
// ~c: Does nothing it is a pointer.
// ~b: destroyes b via Y::~Y()
// ~a: Does nothing as POD has not destructr.
// ~Z(): Destory base class.
X::(X const& rhs)
:Z(rhs)
,a(rhs.a)
,b(rhs.b)
,c(rhs.c)
{}
X& operator=(X const& rhs)
{
Z::operator=(rhs);
a = rhs.a;
b = rhs.b;
c = rhs.c;
return *this;
}
Something* something = new Something();
...然后调用"operator new"(默认的operator new将从堆中分配内存),然后在新分配的内存上调用构造函数。或者,如果您这样做:
Something something;
...然后在堆栈上分配(或保留)一些内存,然后在新分配/保留的内存上调用构造函数。
它类似于其他所有非静态方法(包括析构函数),因为有一个“this”指针:不同之处在于当调用构造函数时,将包含“this”的内存刚刚被分配但尚未初始化(这就是构造函数所做的:它初始化“this”)。