首页 > 编程语言 > 详细

c++构造函数详解

时间:2015-07-17 00:29:39      阅读:242      评论:0      收藏:0      [点我收藏+]

一、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之前。

 

 

版权声明:本文为博主原创文章,未经博主允许不得转载。

c++构造函数详解

原文:http://blog.csdn.net/lqlblog/article/details/46919363

踩
(0)
赞
(0)
   
举报
评论 一句话评论(0)
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!