C++对象模型(一):The Semantics of Constructors The Default Constructor (默认构造函数什么时候会被创建出来)
本文是 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 (默认构造函数什么时候会被创建出来)的更多相关文章
- The Semantics of Constructors: The Default Constructor (默认构造函数什么时候会被创建出来)
		
本文是 Inside The C++ Object Model, Chapter 2的部分读书笔记. C++ Annotated Reference Manual中明确告诉我们: default co ...
 - The Semantics of Constructors(拷贝构造函数之编译背后的行为)
		
本文是 Inside The C++ Object Model's Chapter 2 的部分读书笔记. 有三种情况,需要拷贝构造函数: 1)object直接为另外一个object的初始值 2)ob ...
 - C++对象模型——默认构造函数的合成
		
最近在学习C++对象模型,看的书是侯捷老师的<深度探索C++对象模型>,发现自己以前对构造函数存在很多误解,作此笔记记录. 默认构造函数的误解 1.当程序猿定义了默认构造函数,编译器就会直 ...
 - C++对象模型——Default Constructor的建构操作(第二章)
		
第2章 构造函数语意学 (The Semantics of Constructor) 关于C++,最常听到的一个抱怨就是,编译器背着程序猿做了太多事情.Conversion运算符就是最常被引用的 ...
 - 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 ...
 - C++对象模型的那些事儿之三:默认构造函数
		
前言 继前两篇总结了C++对象模型及其内存布局后,我们继续来探索一下C++对象的默认构造函数.对于C++的初学者来说,有如下两个误解: 任何class如果没有定义default constructor ...
 - 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 ...
 - “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 ...
 - 深度探索C++对象模型之第二章:构造函数语意学之Default constructor的构造操作
		
C++新手一般由两个常见的误解: 如果任何class没有定义默认构造函数(default constructor),编译器就会合成一个来. 编译器合成的的default constructor会显示的 ...
 
随机推荐
- JConsole/JvisualVM 远程连接失败处理
			
今天在使用JConsole进行远程连接时,发现IP和端口在Windows下是可以远程telnet的,但是,使用JConsole时却无法连接. 我的环境如下: Windows下运行JConsole,准备 ...
 - 《读书报告 -- Elasticsearch入门 》--简单使用(2)
			
<读书报告 – Elasticsearch入门 > ' 第四章 分布式文件存储 这章的主要内容是理解数据如何在分布式系统中存储. 4.1 路由文档到分片 创建一个新文档时,它是如何确定应该 ...
 - MacOS下Rails+Nginx+SSL环境的搭建(下)
			
五.以Production环境部署Rails项目 这里插一个题外话,我们之前是以development环境运行的rails项目,现在我们希望在实际的生产系统中跑一下看看.这是十分有必要的,应该在rai ...
 - 《Java多线程编程核心技术》推荐
			
写这篇博客主要是给猿友们推荐一本书<Java多线程编程核心技术>. 之所以要推荐它,主要因为这本书写得十分通俗易懂,以实例贯穿整本书,使得原本抽象的概念,理解起来不再抽象. 只要你有一点点 ...
 - Dynamics CRM  构建IN查询
			
CRM中有3种查询数据的方式,分别是QueryExpression.fetchxml.linq,本篇讲述的条件IN的查询只支持前两种,linq并不支持. QueryExpression的写法如下,示例 ...
 - 算法之路(三)----查找斐波纳契数列中第 N 个数
			
算法题目 查找斐波纳契数列中第 N 个数. 所谓的斐波纳契数列是指: * 前2个数是 0 和 1 . * 第 i 个数是第 i-1 个数和第i-2 个数的和. 斐波纳契数列的前10个数字是: 0, 1 ...
 - 打开Voice Over时,CATextLayer的string对象兼容NSString和NSAttributedString导致的Crash(一现象)
			
一.现象:iPhone真机打开Voice Over的情况下,iPhone QQ空间工程,Xcode 真机编译启动必Crash,main函数里面 NSSetUncaughtExceptionHandle ...
 - java基础知识——网络编程、IO流
			
IO流 字节流:处理字节数据的流对象,计算机中最小数据单元就是字节.InputStream OutputStream 字符流:字符编码问题,将字节流和编码表封装成对象就是字符流.Reader Writ ...
 - python+OpenCV 特征点检测
			
1.Harris角点检测 Harris角点检测算法是一个极为简单的角点检测算法,该算法在1988年就被发明了,算法的主要思想是如果像素周围显示存在多于一个方向的边,我们认为该点为兴趣点.基本原理是根据 ...
 - 15 Action View 以及监听 的使用
			
menu 代码 <menu xmlns:android="http://schemas.android.com/apk/res/android" > <!-- a ...