如果一个类没有任何constructor,那么会有一个default constructor被隐式的声明出来,一个implicit default constructor将是一个trivial(无用的)constructor。但是在某些情况下,implicit default constructor将是一个nontrivial constructor,下面一一讨论:

由编译器合成nontrivial default constructor的四种情况:

1)带有default constructor 的 member class object(ps:不包括基本数据类型对象):

  • case 1:如果一个类没有任何constructors,但它包含一个member class object,那么这个类的implicit default constructor 会去调用member class object的default constructor。
class A
{
public:A(){cout<<"Class A Constructor!"<<endl;}
};class B
{
public:A a;   // a is a member class object and class A has a default constructor.
};
void main()
{B b;
}

  • case 2:如果一个类包含constructors(ps:不限定是default constructor),也包含带default constructor的member class object,但是没有在constructors中显示调用,那么编译器会扩张已存在的constructors,使其每个member class object得到初始化。
class A
{
public:A(){cout<<"Class A Constructor!"<<endl;}
};
class B
{
public:B(int){}  // Non-default constructorA a;   // a is a member class object and class A has a default constructor.
};
void main()
{B b(5);
}

  • case 3:C++中以member class object 在类中的声明顺序来调用各个constructors。
class A
{
public:A(){cout<<"Class A Constructor!"<<endl;} // Default constructor
};
class B
{
public:B(){cout<<"Class B Constructor!"<<endl;}  // Default constructor
};
class C
{
public:A a;  // Member class objectB b;  // Member class object
};
void main()
{C c;
}

2)带有default constructor 的 base class:
  • case 1:如果一个类没有任何constructors,但它派生自一个或多个带有default constructor 的 base class,那么这个类的implicit default constructor 会去调用base class 的 default constructor(按声明顺序调用)。
class A
{
public:A(){cout<<"Class A Constructor!"<<endl;} // Default constructor
};
class B : public A{};
void main()
{   B b;
}

  • case 2:如果一个类包含constructors(ps:不限定是default constructor),且派生自一个或多个带有default constructor 的 base class,但是没有在constructors中显示调用,那么编译器会扩张已存在的constructors,使其每个上层base class 的 default constructor 得到调用(按声明顺序调用)。
class A
{
public:A(){cout<<"Class A Constructor!"<<endl;} // Default constructor
};
class B : public A
{
public:B(){}
};
void main()
{  B b;
}

3)带有一个或多个virtual functions 的 class:
  • class声明(或继承)一个或多个virtual functions,那么编译器会在constructors(如果没有,则隐式创建一个default constructor)中隐式的进行一些扩张行动:创建一个virtual function table,内放class 的 virtual functions的地址(所以一个类中如果声明了virtual function(纯虚函数除外),就必须实现它,实现了才会有函数地址);在每一个class object中,创建一个额外的vft_ptr,内含virtual function table的地址。
// sizeof(A)=1
class A
{
public:A(){cout<<"Class A Constructor!"<<endl;} // Default constructor
};// sizeof(A)=4
class A
{
public:A(){cout<<"Class A Constructor!"<<endl;} // Default constructorvirtual void foo(){}
};

4)带有一个或多个virtual base class 的 class:

  • class或继承一个或多个virtual base class,那么编译器会在constructors(如果没有,则隐式创建一个default constructor)中隐式的进行一些扩张行动:创建一个virtual base class table,内放virtual base class subobjects 的地址(所以要virtual派生自一个base class,那么这个base class必须提供default constructor,使得编译器能创建virtual base class 的 subobject);在每一个class object中,创建一个额外的vbt_ptr,内含virtual base class table的地址。
// sizeof(B)=1
class A{};
class B : public A{};
// sizeof(B)=4
class A{};
class B : public virtual A{};

总结:以上四种情况,会造成编译器为未声明constructor的类隐式生成一个default constructor,或者扩张已有的constructors使其满足编译器的需要。

转载于:https://www.cnblogs.com/newhand-liu/archive/2012/05/26/2793274.html

Chap2-构造函数语意学相关推荐

  1. C++构造函数语意学

    C++构造函数语意学 默认构造函数的构造操作 拷贝构造函数的构造操作 程序转换语意学 成员初始化列表 默认构造函数的构造操作 考虑如下代码: class Foo {public:int val;Foo ...

  2. 《深度探索C++对象模型》--2 构造函数语意学

    1.default constructor的构造操作 C++standard:对于class X,如果没有任何user-declared constructor,那么会有一个default const ...

  3. C++对象模型学习——构造函数语意学

    2019独角兽企业重金招聘Python工程师标准>>> 一.Defalut Constructor的构造函数 C++ Standard [ISO-C++95]的Section12.1 ...

  4. C++ 对象模型 第二章 构造函数语意学

    目录 2.1 默认构造函数的建构操作 2.2复制构造函数的建构操作 2.2.1 位逐次拷贝 2.2.2 不进行位逐次拷贝 2.2.3 重新设定虚函数表的指针 2.3 成员们的初始化队伍 2.1 默认构 ...

  5. 深度探索C++对象模型 学习笔记 第二章 构造函数语意学

    很多人抱怨说C++背着程序员做了太多事,如: if (cin) { /* ... */ } 为了让cin能转换为真假值,为cin定义一个类型转换运算符operator int(),就可以完成以上工作了 ...

  6. 【C++对象模型】第二章 构造函数语意学

    1.Default Constructor 当编译器需要的时候,default constructor会被合成出来,只执行编译器所需要的任务(将members适当初始化). 1.1  带有 Defau ...

  7. [读书笔记] - 《深度探索C++对象模型》第2章 构造函数语意学

    Table of Contents 1.Default Constructor的建构操作 1.2 nontrivial default constructor四种情况 1.2.1"带有Def ...

  8. C++编译器会对没有构造函数的类生成默认构造函数吗?

    之前在上C++的课的时候,印象中有那么一句话: 如果一个类没有任何构造函数,那么编译器会生成一个默认的构造函数 今天在看<深度探索C++对象模型>的第二章:"构造函数语意学&qu ...

  9. 深度探索C++对象模型第2章 构造函数语义学

    默认构造函数 两个误区: 1 任何class如果没有定义默认构造函数,就会被合成一个出来:只有在某些情况下被合成 2 编译器合成出来的默认构造函数会明确设定class中每一个数据成员的默认值 :默认值 ...

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

    来源:http://dsqiu.iteye.com/blog/1669614 之前一直对C++内部的原理的完全空白,然后找到<Inside The C++ Object Model>这本书 ...

最新文章

  1. 河南大学明德计划2020计算机学院,河南大学启动“明德计划”
  2. Python语言环境错误:不支持的语言环境设置
  3. php mysql log文件怎么打开_如何查看mysql的日志文件
  4. (仿头条APP项目)3.二级页面首页的ViewPager页面切换
  5. 攻防世界-web-ics-07-从0到1的解题历程writeup
  6. C/C++新建注册表项实例
  7. 可视化流程设计器 Activiti Designer
  8. JAVA反射机制初步理解
  9. PythonGuru 中文系列教程·翻译完成
  10. 上海芯导电子科技股份有限公司IPO过会
  11. cacti的安装与配置(一)安装
  12. 达梦8数据库安装教程
  13. 二分查找和三分求单峰函数极值
  14. 好系统重装助手教你win10系统连接XP系统共享打印机的方法
  15. 使用rundll32.exe运行dll函数
  16. ADAU1860调试心得(13)DSP实现滤波器算法
  17. 基于Canal+kafka监听数据库变化的最佳实践
  18. 基于javaweb(springboot)汽车配件管理系统设计和实现以及文档报告
  19. 三本可爱小表妹,面试小米Java技术岗经验分享(已拿offer)
  20. 现代密码学期末复习26问

热门文章

  1. koa --- restful规范及其栗子
  2. javascript --- 在linux上部署项目
  3. vue --- 基本的表单元素
  4. ES5-13 对象属性遍历、this、callee、caller
  5. Linux中的cron计划任务配置详解
  6. 为Tiny4412设备驱动在proc目录下添加一个可读版本信息的文件
  7. 自然语言交流系统 phxnet团队 创新实训 项目博客 (五)
  8. Reflux系列01:异步操作经验小结
  9. 灾备还缺一套评价体系
  10. 由于远程桌面服务当前正忙|VDI无法连接