一、Default constructor

1.       对于class X ,假设没有不论什么user-declared
constructor,那么编译器生成的default constructor是没用的

2.       编译器合成(扩张)的default constructor 是实用的4中情况

①.带有default constructor的member
class object

Member class object 的Default constructor会在合成(扩张)的default
constructor调用。

②.带有default constructor的base
class

合成(扩张)的default constructor会调用base class的default
constructor

③.带有一个virtual funtion的class

合成(扩张)的default constructor会初始化类的vptr

④.带有一个virtual base class的class

3.       误区

①.不论什么class假设未定义default
constructor,就会被合成出来。

②.编译器合成出来的default constructor 会被明白设定class内的每个data
member的默认值。

二、Copy constructor

1.       有三种情况,会以一个object的内容作为还有一个class的初值。

①.明白的以一个object的内容作为还有一个class
object的初值 X xx = x;

②.当object被当作參数交给某个函数时 void
foo(X x)

③.当函数传回一个class object   x = foo() { return
xx;}

假设定义了copy constructor则大多数情况下会被调用,否则其内部是以所谓的default memberwise initialization 手法完毕,对于当中member
class object是以递归方式施行memberwise initialization。

2.       编译器会合成copy constructor的情况即class不表现出bitwise
copy semantics

①.当class内含一个member
object而后者的class声明有一个copy constructor时(具备条件合成的)

②.当class继承自一个base
class而后者存在有一个copy constructor(被明白声明或被合成)

③.当class声明了一个或多个virtual
funtions时

④.当class派生自一个继承串链,当中有一个或多个virtual
base classes时

以下对第三点做简要说明:

我们知道编译期间的两个程序扩张操作(有virtual funtion存在的前提下)

I.添加一个virtual function table(vtbl),内含每个有作用的virtual
function的地址

II.将一个指向virtual function table的指针(vptr),安插在每个class
object内

从这两点我们能够看出编译器须要合成出一个copy constructor以求将vptr适当的初始化。

class ZooAnimal

{

public:

ZooAnimal(){}

virtual ~ZooAnimal(){}

virtual void animate(){}

virtual void draw() {}

};

class Bear : public ZooAnimal

{

public:

Bear(): b(5){memset(this, 0, sizeof(Bear));}

virtual void animate(){}

virtual void draw() {}

virtual void dance(){}//父类没有的虚函数

};

Bear yogi;

Bear winnine = yogi;

这样的情况下yogi的vptr值拷贝给winner的vptr是安全的,也就说此时两个对象的vptr全然一样。

可是以下这样的情况

ZoonAnimal franny = yogi;

此时franny的vptr不能够被设定指向Bear
class的virtual table。也就说合成出来的ZoonAnimal copy constructor会明白设定object的vptr指向ZoonAnimal
class的virtual table。而不是直接从右手边的class object将其vptr现值拷贝过来

三、成员初值列(member initialization list)

1.       为了通过编译必须使用member initialization list的情况

① 当初始化一个reference member

② 当初始化一个const member

③ 当调用一个base class的constructor,而它拥有一组參数时

④ 当调用member class的constructor,而它拥有一组參数时

初始化顺序不是有list中的项目顺序而是有member声明次序决定;编译器会一一操作initialization
list依据声明次序在constructor内安插初始化操作,而且在不论什么explicit user code之前。

最新文章

  1. [No0000A9]实用word用法
  2. C3P0连接池配置和实现详解
  3. linux下的常用命令
  4. MongoDB使用小结:一些不常见的经验分享
  5. 【蛙蛙推荐】Lucene.net试用
  6. 把properties放到src的package中
  7. NYOJ-44 子串和 AC 分类: NYOJ 2014-01-04 22:53 154人阅读 评论(0) 收藏
  8. Android FastJson解析
  9. 基于位运算符的IP和数值转换
  10. iOS文档序列化(对象归档)
  11. 学习python登录demo
  12. 使用C++的string实现高精度加法运算
  13. Cocos2D中相关问题提问的几个论坛
  14. Spring Boot 集成 Swagger,生成接口文档就这么简单!
  15. Windows环境下应用Java代码操作Linux资源
  16. EChart.js 简单入门
  17. SVN客户端操作
  18. luogu P3162 [CQOI2012]组装
  19. 《Effective Modern C++》翻译--条款2: 理解auto自己主动类型推导
  20. C#获取文件类型

热门文章

  1. bash编程之 ~制作Mini Linux系统~
  2. centos配置虚拟主机virtualhost,让服务器支持多网站多域名(转)
  3. checked和unchecked的区别
  4. UI---------EventSystem
  5. DevExpress 利用DateEdit 仅显示和选择年份 z
  6. EntityFramework(EF)贪婪加载和延迟加载的选择和使用
  7. [翻译] SWTableViewCell
  8. TR069协议小结
  9. Android图片加载框架最全解析(二),从源码的角度理解Glide的执行流程
  10. ping + 时间 日志