编译器与默认构造函数
来源:互联网 发布:1024最新 知乎 编辑:程序博客网 时间:2024/05/01 11:40
C++新手一般有两个常见的误解:
a. 任何一个class如果没有定义default constructor,就会被合成一个出来
b. 编译器合成出来的default constructor会明确设定class内每一个data member的默认值。
对于问题1,C++ Standard规定:
对于class X, 如果没有任何user-declared constructor, 那么会有一个default constructor被implicitly 声明出来, 一个被暗中声明出来的default constructor,将是一个trivial constructor, 即,在函数体内没有逻辑的处理,连赋值都没有。而这样的constructor,编译器实际上并不会真的把他们合成出来。
对于问题2,C++ Standard规定:
在合成default constructor时,只有关于class object的部分会被初始化,所有其他的nonstatic data member,都不会被初始化,因为这些对编译器来说不是必要的。
那么什么时候,编译器必须要合成一nontrivial的default constructor呢?
(1)如果class A内含一个的member class object B, 且该B带有自定义的default constructor。
很明显,如果编译器认为class A声明的还是trivial constructor, 那么编译器就不可能用通用的语意,来构造B, 因为B的default constructor很可能带有自定义逻辑,是nontrivial,必须被调用,这与在函数体内没有逻辑的处理,连赋值都没有是冲突的。
那么就必须在构造时,为A合成一个default constructor,在合成的函数体内包含能够调用B的default constructor,如果有多个member objects, 那么C++语言要求以member objects在class 中的声明次序,来调用各个default constructors。
(2)如果一个没有任何constructors的class A派生自一个“带有default constructor”的base class C
很明显,如果编译器认为class A声明的还是trivial constructor, 那么编译器就不可能用通用的语意,来构造基类C, 因为C的default constructor很可能带有自定义逻辑,是nontrivial,必须被调用,这与在函数体内没有逻辑的处理,连赋值都没有是冲突的。
那么就必须在构造时,为A合成一个default constructor,在合成的函数体内包含能够调用C的default constructor, 需要注意的是,如果A提供多个constructors,但其中都没有default constructor,那么编译器会扩张现有的每一个constructors,将“用以调用所有必要之default constructors”的代码加进去,而不会合成一个新的default constructor.
(3)class声明或继承一个virtual function
由于一个virtual function table -- vptr, 会被编译器产生出来,内放class的virtual functions地址。
为了给vptr设定初始,放置适当的virtual table地址,编译器会为他们合成一个默认构造函数,以便正确的初始化每一个class object的vptr.
(4) class派生自一个继承串链,其中有一个或更多的虚基类
所有经由reference或pointer来存取一个virtual base class的操作,都可以通过为每一个virtual base classes 安插一个指针,来完成。这个工作由编译器为构造函数合成。
综上所述,如果编译器认为,当前默认构造函数不需要添加任何逻辑操作,就不会被合成,否则,就在调用时,被合成出来。
参考自
C++ Object Model --- The Semantics of Constructors
- 编译器与默认构造函数
- C++构造与析构(14) - 编译器何时创建默认构造函数和拷贝构造函数
- 编译器何时调用默认构造函数
- c++编译器什么时候生成默认构造函数
- new与默认构造函数
- C++编译器合成默认构造函数的条件(合成默认拷贝构造函数雷同)
- C++编译器提供默认构造函数的几种情况
- C++编译器何时为用户提供默认构造函数
- 编译器提供默认构造函数的几种情况
- C++编译器何时为用户提供默认构造函数
- C++编译器何时为用户提供默认构造函数
- C++ 编译器生成默认构造函数的四种情况
- C++编译器何时为用户提供默认构造函数
- 编译器自动生成默认构造函数的情况
- C++ 编译器生成默认构造函数的四种情况
- c++编译器何时会生成默认构造函数
- C++ 编译器生成默认构造函数的四种情况
- C++编译器合成默认构造函数的真相
- assert 断言函数/宏
- java环境变量设置
- sscanf高级用法
- hdu_1531 还是差分约束
- java mail SMTP 发送验证代码 javax.mail.AuthenticationFailedException
- 编译器与默认构造函数
- 纯用SSH管理GIT服务器
- Oracle使用和开发过程中常见错误
- MVC之我见
- No 121 · android手机连接电脑网络设置
- Hibernate
- getResourceAsStream, 修改war包内的文件
- 在命令行下,如何使用JAD反编译jar文件 .
- android入门-------案例八(启动带有返回值的activity)