Default Constructor的构造操作
Default Constructor的构造操作
C++ Annotated Reference Manual书中的Section 12.1说过:default constructor 只有在编译器需要的时候才会被编译器合成出来。
C++ Standard修改了C++ ARM的说法,但实际上的行为是一样的。C++ Standard[ISO-C++95]的Section 12.1说到:对于class X,如果没有任何user-declared constructor,那么会有一个default constructor被隐式(implicitly)声明出来。不过这样的隐式声明的default constructor将是一个trivial(无用的)constructor。也就是所谓的implicit trivial default constructor,它们实际上并不会被合成出来。
那到底声明才是C++ ARM所说的编译器需要的情况呢?
第一,“带有Default Constructor”的Member Class Object
如果一个class X没有任何constructor,但它有至少一个member object,而这个member object对应的class有default constructor,那么编译器就需要为class X合成一个default constructor。不过这个合成操作只有在constructor被调用的时候才会发生。
举个例子:
class Foo { public : Foo(), Foo(int)…};
class Bar {pubcli Foo foo; char *str;};
void foo_bar()
{
Bar bar; // Bar:foo 必须在此处初始化。
}
被合成的default constructor看起来可能像这样(省略this指针):
inline
Bar::bar()
{
foo.Foo::Foo();
}
第二,“带有Default Constructor”的Base Class
与第一点类似,如果一个没有任何constructor的class派生自一个“带有Default Constructor”的base class,那么编译器会为这个derived class合成一个default constructor,它将调用上一层base classes的default constructor(根据它们声明顺序)。如果同时存在第一点和第二点的情况,则member class objects constructor会在所有base class constructor之后再调用。
第三,“带有至少一个Virtual Function”的Class
编译器会为每一个“带有至少一个Virtual Function”的class object的vptr(指向virtual table)设定初值。对于一个没有任何constructor的class,编译器会为它合成一个default constructor,以便正确地初始化每一个class object的vptr。
第四,“带有至少一个Virtual Base Class”的Class
Virtual base class的实现法在不同的编译器之间有极大地差异。然而,每一种实现法的共同点在于必须使virtual base class在其每一个derived class object中的位置,能够于执行期准备妥当。
举个例子:
class X { public: int i;};
class A : public virtual X {public: int j;};
class B : public virtual X {public: double d;};
class C : public A, public B {public: int k;};
// 无法在编译期决定pa->X::i的实际偏移位置
void foo(const A* pa) {pa->i = 1024;}
main()
{
foo(new A);
foo(new B);
}
编译器无法固定住foo()之中“经由pa而存取的X::i”的实际偏移位置,因为pa的真正类型可以改变。编译器必须改变“执行存取操作”的那些代码,使X::i可以延迟至执行期才决定下来。
对于一个没有任何constructor的class,编译器会为它合成一个default constructor,在这个default constructor中会安插那些“允许每一个virtual base class的执行期存取操作”的代码。
总结,在以上4种情况,“编译器必须为未声明constructor的classes合成一个default constructor”。C++ Standard把那些合成物称为implicit nontrivial default constructor。被合成出来的constructor只能满足编译器(而非程序)的需要。它之所以能够完成任务,是借着“调用member object或base class的default constructor”或是“为每一个object初始化其virtual function机制或virtual base class机制”而完成的。至于不存在那4中情况而又没有声明任何constructor的classes,我们说它拥有的是implicit trivial default constructor,它们实际上并不会被合成出来。
注意:
1、在合成的default constructor中,只有base class subobjects和member class objects会被初始化。所有其他的nonstatic data member(如整数,整数指针,整数数组等等)都不会被初始化。这些初始化操作对于编译器都是非必要的,提供这些初始化操作的应该是程序员而不是编译器。
2、不是任何没有定义default constructor的class都会生成一个implicit default constructor。
3、编译器合成的default constructor不会显示设定“class 内每一个data member的默认值”。
Default Constructor的构造操作的更多相关文章
- 深度探索C++对象模型之第二章:构造函数语意学之Default constructor的构造操作
C++新手一般由两个常见的误解: 如果任何class没有定义默认构造函数(default constructor),编译器就会合成一个来. 编译器合成的的default constructor会显示的 ...
- Copy Constructor的构造操作
Copy Constructor的构造操作 有三种情况,会以一个object的内容作为另一个class object的初值: 1. 对一个object做显式的初始化操作 class X{…}; X ...
- C++对象模型——Default Constructor的建构操作(第二章)
第2章 构造函数语意学 (The Semantics of Constructor) 关于C++,最常听到的一个抱怨就是,编译器背着程序猿做了太多事情.Conversion运算符就是最常被引用的 ...
- 深度探索C++对象模型之第二章:构造函数语意学之Copy constructor的构造操作
C++ Standard将copy constructor分为trivial 和nontrivial两种:只有nontrivial的实例才会被合成于程序之中.决定一个copy constructor是 ...
- 构造函数语义学——Copy Constructor 的构造操作
前言 在三种情况下,会以一个 object 的内容作为另一个 class object 的初值: object明确初始化 class X{...}; X x; X xx = x; object 被当作 ...
- 构造函数语义学之Default Constructor构建操作
一.Default Constructor的构建操作 首先大家要走出两个误区: 1).任何class如果没有定义default constructor,就会被合成一个来. 2).便以其合成出来的def ...
- C++对象模型(一):The Semantics of Constructors The Default Constructor (默认构造函数什么时候会被创建出来)
本文是 Inside The C++ Object Model, Chapter 2的部分读书笔记. C++ Annotated Reference Manual中明确告诉我们: default co ...
- 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 ...
- 构造函数语义学——Default Constructor篇
构造函数语义学--Default Constructor 篇 这一章原书主要分析了:编译器关于对象构造过程的干涉,即在对象构造这个过程中,编译器到底在背后做了什么 这一章的重点在于 default c ...
随机推荐
- Openjudge-NOI题库-字符串移位包含问题
题目描述 Description 对于一个字符串来说,定义一次循环移位操作为:将字符串的第一个字符移动到末尾形成新的字符串. 给定两个字符串s1和s2,要求判定其中一个字符串是否是另一字符串通过若干次 ...
- mob.com Android studio 配置环境
- swift label不同颜色、不同字体
let string = "点击注册按钮,即表示您已同意隐私条款和服务协议" let ranStr = "同意" let attrstring:NSMutabl ...
- delphi 快捷键大全
************************* 1.功能键 2.组合键 3.其他快捷键 4.补充 5.补充1(带分类) 6.补充2 --Edit by 2013.1.14 ************ ...
- chrome devtools
Elements chrome devtools 中 Elements panel 是审查 dom 元素和 css 的, 可以实时修改 dom/css. windows: ctrl + shift + ...
- django 安装记录
1. 下载django安装包,下载个最新的安装包即可. https://www.djangoproject.com/download/ 2. 在本地解压 tar -xvf 安装包名称 3. 安装 ...
- 【Python之路】第四篇--Python基础之函数
三元运算 三元运算(三目运算),是对简单的条件语句的缩写 # 书写格式 result = 值1 if 条件 else 值2 # 如果条件成立,那么将 “值1” 赋值给result变量,否则,将“值2” ...
- 解决maven web项目Cannot detect Web Project version. Please specify version of Web Project through...的错误
前面已经创建maven web工程,但是问题来了,创建maven web工程之后会出现如下的错误,在pom.xml文件头部 有以下的错误 Description Resource Path Locat ...
- WEB 技术分类 Javascript DOM(Element Node) BOM
Web technology for developers Web 技术文档 备注:本文介绍web technology的分类,各自职责,因为之前一直就没有搞明白各种技术.各种名词究竟是属于哪个范 ...
- Android Studio 中提示 Private field 'mType' is assigned but never accessed 的原因
Android Studio 是个很酷的编译器,之前发现有个代码提示很奇怪,但无奈一直没看懂他的意思,不过也没报错就没太在意,刚刚突然领悟了,原来是自己代码不规范. Private field 'mT ...