声明或定义一个类/对象的时候,会因为类本身的成员结构而会引起不同的构造函数的调用,之前的学习中或多或少有些总结。《c++primer(第五版)》《深度探索c++对象模型》《More Effective C++》三本书中都有总结,自己也简单的理解了下
全篇总结:
一,声明一个类对象时,不一定是调用了默认的构造函数;只有在没有任何构造函数且AA xx{}声明的时候,编译器才会对内置类型进行“零值化”;其他情况按照四种情况进行分析
二,编译器有四种情况会合成默认的构造函数
1. 包含了一个类的对象,这个对象有一个构造函数(包括编译器合成的默认构造函数)
2. 继承自一些基类,其中某些基类有一个构造函数(包括编译器合成的默认构造函数)
3. 有一个虚函数,或者继承到了虚函数
4. 有虚基类
两种错误的观点:
a) 任何类如果没有定义构造函数,则编译器会帮我们合成一个默认构造函数。
b) 合成默认构造函数会对类中的每一个数据成员进行初始化。
三,new对象的时候带不带括号
对于自定义类类型:
如果该类没有定义构造函数(由编译器合成默认构造函数)也没有虚函数,那么class c = new class;将不调用合成的默认构造函数,而class c = new class();则会调用默认构造函数。
如果该类没有定义构造函数(由编译器合成默认构造函数)但有虚函数,那么class c = new class;将不调用合成的默认构造函数;class c = new class()会调用默认构造函数。
如果该类定义了默认构造函数,那么class c = new class;和class c = new class();一样,都会调用默认构造函数。。
对于内置类型:
int *a = new int;不会将申请到的int空间初始化,而int *a = new int();则会将申请到的int空间初始化为0。
1,声明一个类的时候,不一定是调用了默认构造函数
如下:
class HasExplicitCon{
public:
HasExplicitCon(){
cout<<"显式的定义一个默认构造函数"<<endl;
}
HasExplicitCon(int a){
cout<<"显式的定义一个有参数默认构造函数"<<endl;
}
int a;
};
int main(int argc, char **argv) {
HasExplicitCon hasObject1;
HasExplicitCon hasObject2(2);
HasExplicitCon hasObject3();
cout<<hasObject1.a<<endl;
cout<<hasObject2.a<<endl;
//cout<<hasObject3.a<<endl; 编译不通过
return 0;
}
结果为:
显式的定义一个默认构造函数
显式的定义一个有参数默认构造函数
4213675
7602016
是的,没看错,结果只输出了两行,因为hasObject3后面跟的是小括号,会引起c++歧义,误以为是定义的一个函数,这点在之前的文章中说过了http://blog.csdn.net/hll174/article/details/78309212。用中括号的话则不会,中括号实际是initializer_list,http://zh.cppreference.com/w/cpp/language/list_initialization
std::initializer_list 对象在这些时候自动构造:
- 花括号初始化器列表用于列表初始化,包括函数调用列表初始化和赋值表达式
- 花括号初始