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,都不会被初始化,这些工作应该由设计者(程序猿)而不是编译器去完成。

时间: 2024-12-02 13:06:46

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

深度探索C++对象模型--------默认构造函数

一:默认构造函数的构建      默认构造函数总是在被需要的时候构建出来!!关键字"被需要的时候"!! class Foo { public: int val; Foo *next; }; void foo_bar() { Foo bar; if(bar.val || bar.next) //do something } 上述的代码,编写者意图对象bar中的data member val 和 next 为0.但是编译器没有义务为你初始化为.首先对于堆栈中的变量都不一定会被初始化为0,而

Linux Debugging(四): 使用GDB来理解C++ 对象的内存布局(多重继承,虚继承)

      前一段时间再次拜读<Inside the C++ Object Model> 深入探索C++对象模型,有了进一步的理解,因此我也写了四篇博文算是读书笔记: Program Transformation Semantics (程序转换语义学) The Semantics of Copy Constructors(拷贝构造函数之编译背后的行为) The Semantics of Constructors: The Default Constructor (默认构造函数什么时候会被创建出

MediaRecorder test

public class MediaRecorder extends Object java.lang.Object    ↳ android.media.MediaRecorder Class Overview Used to record audio and video. The recording control is based on a simple state machine (see below). A common case of using MediaRecorder to r

《Android游戏开发详解》一3.1 构造方法

3.1 构造方法 Android游戏开发详解通过回顾第2章中的重要概念并且做一些小的修改,我们可以更容易地进入较为复杂的主题.首先创建一个名为Constructors的项目,并且创建一个World类,如程序清单3.1所示. 程序清单3.1 World.java 1 public class World { 2 3 public static void main(String[] args) { 4 5 6 } 7 8 } 我们还将创建一个名为Coder的类,如程序清单3.2所示. 程序清单3.2

C++对象模型(二):The Semantics of Copy Constructors(拷贝构造函数之编译背后的行为)

本文是 Inside The C++ Object Model's Chapter 2  的部分读书笔记. 有三种情况,需要拷贝构造函数: 1)object直接为另外一个object的初始值 2)object作为函数以值传递的参数 3) object以函数返回值形式返回 如果class没有提供一个explicit copy constructor时,编译器会以default memberwise initialization,也就是把每一个内建的或者派生的data member的值,从某个obj

《深度探索C++对象模型(Inside The C++ Object Model )》学习笔记

来源:http://dsqiu.iteye.com/blog/1669614 之前一直对C++内部的原理的完全空白,然后找到<Inside The C++ Object Model>这本书看了下, 感觉收获很大,因为书写得比较早,有些知识应该要更新,但是还是值得好好研读,由于该书的内容给人比较散的感觉,所以一直想找个时间整理一下,遂成此文,虽然都是抄书上的,但是却让我有了温故而知新的觉悟,附近里有三个好资料,一并共享了!2012年9月2日凌晨 4:31 谢谢 张雨生的歌声的相伴!   <

深度探索C++对象模型(4)

雷神跌跌撞撞的读完了<深度探索C++对象模型>的第一章,虽然还是有些疑惑,但是已经感到收获很大.按照朋友的说法,第一章是一个概括的介绍,具体的细节会在以后的章节阐述,如果没有通读本书,第一章还是比较不容易理解的.雷神听过之后信心倍增,也不在有初看此书时的"世界末日"的感觉了(在第2篇雷神感到学了近一年的C++,居然水平如此之差),并且通过自己的努力,还是摸到了些门道,所以让我们继续快乐的出发,踏上深度探索C++对象模型的旅程.记住我们在第一篇的小文<坚持不懈,直到成功

Crystal 三种报表解决方案大对比:.NET 对象模型,报表应用服务器对象模型,水晶企业对象模型

对象|服务器|解决 概述 对于使用 .NET 平台的 Web 应用程序开发,Crystal Decisions 为开发者提供了三种愈加高级的报表对象模型: 1. 水晶报表 Visual Studio .NET 版 (.NET) 对象模型:捆绑在微软 Visual Studio .NET 和水晶报表 9 开发者版及高级版中. 2. 新增的报表应用服务器 (RAS) 对象模型:捆绑在水晶报表 9 开发者版及高级版中. 3. 水晶企业 (Crystal Enterprise) (CE) 对象模型:在水

An Intro to Constructors in C#

This is an article on Constructors in C#, for the beginner level programmers. It covers simple constructors, constructors overloading, behaviour of constructors in inheritance, constructor chaining and static constructors. At the end, it contains the