本文是 Inside The C++ Object Model, Chapter 2的部分读书笔记。

C++ Annotated Reference Manual中明确告诉我们: default constructor会在需要的时候被编译器产生出来。注意,这里是编译器需要,而不是程序需要。后来的C++ Standard 95修改了这种说法,但是实质上仍是相同的: For class X, if there is none user declared constrator, one default constructor will be implicitly generated by the Compiler.

但实际上,如果default constructor是trivial(无用的),那么编译器根本就不会产生它!只有一下四种情况,non-trivial default constructor会被产生出来,来保证C++语言的机制能够按照预期工作:

1)带有Default Constructor的Member Class Object

如果该class X 包含有带有默认构造函数的成员class object (member object),那么编译器需要对此class X合成一个default constructor。不过该合成只在该合成操作真正被调用时。

被合成的这个default constructor,包含有调用这个member class的default constructor的代码,但是它不会初始化它自身其他的成员变量,比如char *str; int data;这些成员变量的初始化时设计者的责任,而不是编译器的职责!

由此有进一步的思考,如果是设计者已经定义了constructor,来初始化比如char *str; int data; 那么编译器如何初始化其他的member class object呢? 答案就是编译器需要扩张该class的constructor,以按照member class object的声明顺序来调用各个class的default constructor。

2) 带有Default Constructor的Base Class

如果class X继承自一个带有default constructor的class, 那么编译器将为这个class生成non-trivial的default constructor,并且按照base class的顺序逐次调用。

如果user declared 许多constructors,但是没有default constructor(就是没有任何参数的那个constructor),那么编译器不会产生default constructor了。而是扩张每个constructor,使其包含必要的default constructor的扩张代码,比如初始化它的member class object。 参考第一种情况

3) 带有virtual function

对于有virtual function的class,一个virtual function table会被编译器产生出来,存着virtual functions的地址。 而在每一个class的object中,会有一个pointer member(称为vptr)会被编译器生成出来,内容那个class virtual function table的地址。

所以编译器为了使得virtual function的机制生效,必须要为每个这种class的object生成合理的vptr,而vptr的赋值就发上在扩张后的constructors里。如果class没有任何的constructors,那么default constructor会被认为是non-trivial并且会被生成。如果class有constructor/s,那么所有的constructor都会扩张以赋予vptr以合理的值。

4)带有一个virtual base class的class

Virtual base class的实现在不同 的编译器间有极大的差异。共同点就是virtual base class 在其每一个derived class object的位置,在执行期间能够准备妥当。这些工作都要放到constructor中去完成。

总结

  在合成的default constructor中,只有base class subobjects 和member class objects才会初始化。所有其他的nonstatic data member,都不会被初始化,这些工作应该由设计者(程序猿)而不是编译器去完成。

C++对象模型(一):The Semantics of Constructors The Default Constructor (默认构造函数什么时候会被创建出来)的更多相关文章

  1. The Semantics of Constructors: The Default Constructor (默认构造函数什么时候会被创建出来)

    本文是 Inside The C++ Object Model, Chapter 2的部分读书笔记. C++ Annotated Reference Manual中明确告诉我们: default co ...

  2. The Semantics of Constructors(拷贝构造函数之编译背后的行为)

    本文是 Inside The C++ Object Model's Chapter 2  的部分读书笔记. 有三种情况,需要拷贝构造函数: 1)object直接为另外一个object的初始值 2)ob ...

  3. C++对象模型——默认构造函数的合成

    最近在学习C++对象模型,看的书是侯捷老师的<深度探索C++对象模型>,发现自己以前对构造函数存在很多误解,作此笔记记录. 默认构造函数的误解 1.当程序猿定义了默认构造函数,编译器就会直 ...

  4. C++对象模型——Default Constructor的建构操作(第二章)

    第2章    构造函数语意学 (The Semantics of Constructor) 关于C++,最常听到的一个抱怨就是,编译器背着程序猿做了太多事情.Conversion运算符就是最常被引用的 ...

  5. Avoid non-default constructors in fragments: use a default constructor plus Fragment#setArguments(Bundle) instead

    “Avoid non-default constructors in fragments: use a default constructor plus Fragment#setArguments(B ...

  6. C++对象模型的那些事儿之三:默认构造函数

    前言 继前两篇总结了C++对象模型及其内存布局后,我们继续来探索一下C++对象的默认构造函数.对于C++的初学者来说,有如下两个误解: 任何class如果没有定义default constructor ...

  7. Error:Error: Avoid non-default constructors in fragments: use a default constructor plus Fragment#setArguments(Bundle) instead [ValidFragment]

    原文博客链接:https://blog.csdn.net/chniccs/article/details/51258972 在创建fragment时,你可能在打包时碰到如下错误 Error:Error ...

  8. “Avoid non-default constructors in fragments: use a default constructor plus Fragment#setArguments(Bundle)instead”

    “Avoid non-default constructors in fragments: use a default constructor plus Fragment#setArguments(B ...

  9. 深度探索C++对象模型之第二章:构造函数语意学之Default constructor的构造操作

    C++新手一般由两个常见的误解: 如果任何class没有定义默认构造函数(default constructor),编译器就会合成一个来. 编译器合成的的default constructor会显示的 ...

随机推荐

  1. 浅谈static其一之不死变量

    在学习汇编的过程中,小有所悟,遂把自己所思所想记下,以便日后查阅. 首先说说我对这个关键字的理解.static字面上就是静止的.静态的.不变的之类的意思,所以在被它修饰之后,应该也会带有这样的一些特点 ...

  2. 牛客网编程练习之PAT乙级(Basic Level):1041 说反话

    直接分隔取反即可 AC代码: import java.util.Scanner; /** * @author CC11001100 */ public class Main { public stat ...

  3. Bootstrap3 排版-列表

    无序列表 排列顺序无关紧要的一列元素. <ul> <li>...</li> </ul> 有序列表 顺序至关重要的一组元素. <ol> < ...

  4. Swagger API接口管理

    介绍         Swagger API框架,用于管理项目中API接口,属当前最流行的API接口管理工具. Swagger功能强大,UI界面漂亮,支持在线测试等!         Swagger包 ...

  5. UE4使用第三方库读写xml文件

    原文链接:http://gad.qq.com/article/detail/7181031 本文首发腾讯GAD开发者平台,未经允许,不得转载 在游戏开发过程中,读写xml几乎已经成为不可或缺的功能,但 ...

  6. [lua]luasocket.c:20:17: fatal error: lua.h: No such file or directory

    安装luasocket的时候出现了如下的错误 问题 $ tar xzf luasocket-2.0.2.tar.gz $ cd luasocket-2.0.2 $ $ make cd src; mak ...

  7. zookeeper分布式部署方案

    版本:http://apache.fayea.com/zookeeper/zookeeper-3.4.8/环境:debian 7/8说明:最低配置3台步骤:1.下载zookeeper-3.4.8并解压 ...

  8. Django完整的开发一个博客系统

    今天花了一些时间搭了一个博客系统,虽然并没有相关于界面的美化,但是发布是没问题的. 开发环境 操作系统:windows 7 64位 Django: 1.96 Python:2.7.11 IDE: Py ...

  9. 2.6、Android Studio创建可伸缩的图片(9-patch文件)

    Draw 9-patch工具是一个所见即所得编辑器,允许你创建可以自动改变大小来适应视图的内容和屏幕的大小. 以下是使用Draw 9-path工具快速创建一个NinePatch图片. 1. 在命令行中 ...

  10. 6、Android Content Provider测试

    如果你的应用中使用了Content Provider来与其他应用进行数据交互,你需要对Content Provider进行测试来确保正常工作. 创建Content Provider整合测试 在Andr ...