用户未定义默认构造函数时,编译器一定会帮你创建默认构造函数吗?
答:不一定
那么什么时候编译器才会帮创建默认构造函数呢
以下四种情况,用户未定义默认构造函数的情况下编译器才会创建默认构造函数
1、“带有Default Constructor” 的Member Class Object
2、“带有Default Constructor” 的Base Class
3、"带有Virtual Function" 的 Class
4、“带有Virtual Base Class” 的Class
下面对几种情况分别讨论
- “带有Default Constructor” 的成员对象
class A {
public: A();
};
class B {
public:
A a1_;
char* str_;
};
编译器必须为B创建默认构造函数,在该函数内调用a1_.A::A()。编译器只负责初始化a1_,str_的初始化则是程序员自身完成
class A {
public: A();
};
class B {
public:
B() {
str_ = NULL;
}
A a1_;
char* str_; };
这种情况B显示拥有默认构造函数,此时编译器会拓展B(),在用户代码之前添加a1_.A::A()。即B的默认构造函数为
B() { a1_.A::A(); //编译器拓展的代码 str_ = NULL; }
- “带有Default Constructor”的Base Class
和第1种情况类似,编译器必须为B创建默认构造函数,在该函数内调用基类的构造函数A::A()。示例如下:
class A {
public: A();
};
class B : public A
{ public: char* str_; };
- “带有Virtual Function”的Class
class B {
public:
virtual Print();
char* str_; };
示例中当B含有虚函数时,编译器会有其创建默认构造函数,而且还会为其创建virtual function table(vtbl),表项是B的虚函数地址(头部还有一个typeinfo),每个B的对象中,都会添加一个虚表指针(vptr),编译器需要在默认构造函数中为vptr赋值为vtbl的地址
- “带有Virtual Base Class”的Class
示例
class Person {
public:
string name_; };
class Student: virtual public Person
{
public:
int student_id_;
};
class Admin : virtual public Person {
public:
int admin_id_; };
class DSJ : public Student, public Admin {
public:
string dsj_cmd_; };
此时class DSJ只会有一份name_,DSJ对象内部会有一个指针/偏移量指向Person subobject的位置。 这个指针/偏移量的初始化是在DSJ的默认构造函数里。
欢迎交流C++相关技术,技术交流QQ:609400870