C++ 中编译器什么情况才会帮用户创建默认构造函数

用户未定义默认构造函数时,编译器一定会帮你创建默认构造函数吗?

答:不一定

那么什么时候编译器才会帮创建默认构造函数呢

以下四种情况,用户未定义默认构造函数的情况下编译器才会创建默认构造函数

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

 

 

猜你喜欢

转载自blog.csdn.net/songguangfan/article/details/86699045