定义:
默认构造函数(default constructor)就是在没有显式提供初始化式时调用的构造函数。它由不带参数的构造函数,或者为所有的形参提供默认实参的构造函数定义。如果定义某个类的变量(对象)时没有提供初始化式就会使用默认构造函数。
合成的默认构造函数
如果我们的类没有显示地定义构造函数,那么编译器就会为我们隐式地定义一个默认构造函数。这个由编译器创建的构造函数又称为合成的默认构造函数(synthesized default constructor)
合成的默认构造函数只适合非常简单的类,有三个原因:
- 只有当类没有声明任何构造函数的时侯,编译器才会自动地生成默认构造函数。也就是说,当你定义了其他的构造函数时,除非我们再定义一个默认构造函数,否则类将没有默认构造函数。
- 对于某些类来说,合成的默认构造函数可能执行错误的操作。如果类包含有内置类型或者复合类型的成员,则只有当这些成员全都被赋予了类内的初始值时,这个类才适合于使用合成的默认构造函数。
- 有的时候编译器不能为某些类合成默认的构造函数。例如:类中包含一个其他类类型的成员且这个成员的类型没有默认构造函数,那么编译器将无法初始化该成员。这种时候,我们必须自定义默认构造函数,否则该类将没有任何可用的默认构造函数。我们可以使用 = default 要求编译器生成合成的版本(可以对默认构造函数和拷贝控制成员使用)。在新标准下,我们可以定义删除的函数(deleted function)——使用 = delete 。删除的函数是这样一种函数:我们虽然声明了它们,但不能以任何方式来使用它们。
下面提供两个示例供大家理解为什么有的时候编译器不能为某些类合成默认的构造函数:
class test1{ //test1没有默认构造函数
int a;
test1(int x){ //这里声明了其他的构造函数,所以不会有合成的默认构造函数
a = x;
}
};
class test2{
test1 t1; //一个其他类类型的成员
int a;
};
int main(){
test t2; //会报很多错,其中包含:
// error: use of deleted function 'test2::test2()'
// error: no matching function for call to 'test1::test1()'
}
//本例对应情况 1
//如果给test1声明默认构造函数则编译成功
class test1{
int a;
test1() = delete; //使用 =delete 声明
};
int main(){
test1 t1; // error: use of deleted function 'test1::test1()'
}
//对应情况 2
问题:是不是所有的类都有默认构造函数?答案是否定的。
虽然编译器会为类自动生成一个合成的默认构造函数,但是它仅对于包含类类型成员的类。所以对于只含有内置类型或复合类型成员的类,如果不自定义他们的构造函数,编译器不会自动为其生成一个合成的默认构造函数的!