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,都不会被初始化,这些工作应该由设计者(程序猿)而不是编译器去完成。
The Semantics of Constructors: The Default Constructor (默认构造函数什么时候会被创建出来)的更多相关文章
- C++对象模型(一):The Semantics of Constructors The Default Constructor (默认构造函数什么时候会被创建出来)
本文是 Inside The C++ Object Model, Chapter 2的部分读书笔记. C++ Annotated Reference Manual中明确告诉我们: default co ...
- Constructor Overloading in Java with examples 构造方法重载 Default constructor 默认构造器 缺省构造器 创建对象 类实例化
Providing Constructors for Your Classes (The Java™ Tutorials > Learning the Java Language > Cl ...
- C++编译器会对没有构造函数的类生成默认构造函数吗?(有必要的时候才生成,要看情况。有反汇编验证)
之前在上C++的课的时候,印象中有那么一句话:如果一个类没有任何构造函数,那么编译器会生成一个默认的构造函数 今天在看<深度探索C++对象模型>的第二章:“构造函数语意学”的时候发现之前听 ...
- 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 ...
- 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 ...
- 实体类No default constructor found 找不到默认构造函数;
root cause org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [c ...
- C++对象模型——Default Constructor的建构操作(第二章)
第2章 构造函数语意学 (The Semantics of Constructor) 关于C++,最常听到的一个抱怨就是,编译器背着程序猿做了太多事情.Conversion运算符就是最常被引用的 ...
- 构造函数语义学——Default Constructor篇
构造函数语义学--Default Constructor 篇 这一章原书主要分析了:编译器关于对象构造过程的干涉,即在对象构造这个过程中,编译器到底在背后做了什么 这一章的重点在于 default c ...
随机推荐
- Codeforces 1237D. Balanced Playlist
传送门 首先显然的,如果一个位置开始播放了两圈还没结束,那么就永远不会结束 先考虑位置 $1$ 开始播放,用一个 $multisetset$ 维护一下当前听的所有歌,直到某一首歌 $r$ 不合法了就停 ...
- 关于MySQL的索引的几件小事
零.索引简介 1. 索引是什么 ①MySQL官方对索引的定义是:索引(Index)是帮助MySQL高效获取数据的数据结构. ②可以简单的理解为"排好序的快速查找数据结构". ③除了 ...
- Eclipse 设置新建文件默认编码为 utf-8 的方法
选择编辑器顶部 Windows->Preferences->搜索jsp->选择utf-8编码->保存.
- springboot 自动装配
以下内容部分来自小马哥的 <springboot 编程思想> 基础 springboot 项目 maven 依赖 <dependency> <groupId>org ...
- axios表单提交,delete,get请求(待完善)
import { mapMutations} from 'vuex' import axios from 'axios' const mixins = { data() { return { } }, ...
- sql 存储过程笔记2
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[sys_Page_v2]') and OBJECTPROPE ...
- 读书笔记《Oracle从入门到精通》
目录 一.SQL基础 1.SQL种类 2.常用数据类型 3.DDL 4.约束 5.DML语句 二.SELECT语句 1.结果集'*'与指定列 2.拼接符 || 3.substr函数 4.instr函数 ...
- Odoo的菜单项
用户界面的入口是菜单项,菜单项形成一个层级结构,最顶级项为应用,其下一级为每个应用的主菜单.还可以添加更深的子菜单.可操作菜单与窗口操作关联,它告诉客户端在点击了菜单项后应执行什么操作. 菜单项存储在 ...
- SQL语句复习【专题九】
SQL语句复习[专题九] 视图:View视图的概念:视图是从若干基本表或其他视图构造出来的表.在创建一个视图时,只是存放的视图的定义,也即是动态检索数据的查询语句,而并不存放视图对应的数据在用户使用视 ...
- centos nginx https 配置
1,如果想配置一个域名到指定目录咋弄呢?下面这个 server { listen ; server_name 这里换成你的域名,例如baidu.com; set $root_path '/home/w ...