博客园  :: 首页  :: 联系 :: 管理

读书笔记-深度探索C++对象模型-Chapter5

Posted on 2013-03-26 17:06  Apprentice89  阅读(314)  评论(0编辑  收藏  举报

Chapter 5 构造析构拷贝语义学

 

纯虚函数

父类的纯虚函数仍然可以被定义并在子类中以静态方式调用。

对于pure virtual destructor,类的设计者必须定义它,因为每个子类析构时会以静态方式调用其每一个virtual base class和上一层的base classdestructor(如果父类本身不为自己定义析构函数,链接时就找不到这个父类的析构实现,链接错误)。总之,不要把virtual destructor声明为pure

 

 

继承体系下的对象构造

T object;

 

这样的代码在T的构造函数调用时,伴随着的动作有什么:

1.  记录在member init list中的data member会被初始化。

2.  如果有data member没有出现在member init list中,但是它有一个default ctor,则该default ctor会被调用。

3.  在那之前,如果class objectvptr,则vptr需要被设定初值。

4.  在那之前,所有上一层的base class ctor都被调用。

5.  在那之前,所有virtual base class ctor必须被调用。

 

 

如下继承结构下

jc

 

构造函数:

PVertex::PVertex(float x, float y, float z) : _next(0), Vertex3d(x, y, z), Point(x, y) {

    if (spyOn)

       cerr << "within Point3d::Point3d()" << " size: " << size() << endl;

}

 

 

会被编译器扩展为:

PVertex* PVertex::PVertex( Pvertex* this, bool __most_derived, float x, float y, float z )  {

    //有条件地调用virtual base classctor

    if ( __most_derived != false )

       this->Point::Point( x, y );

    //无条件地调用上一层的base classctor

    this->Vertex3d::Vertex3d( x, y, z );

    //初始化vptr

    this->__vptr__PVertex = __vtbl__PVertex;

    this->__vptr__Point__PVertex = __vtbl__Point__PVertex;

 

    //显式的用户代码

    if ( spyOn )

       cerr << "within Point3d::Point3d()"<< " size: "

            // 虚拟机制调用size()函数

            << (*this->__vptr__PVertex[ 3 ].faddr)(this)

            << endl;

    return *this;

}

 

 

对象复制语义学

copy assignment operator

 

 

如下的继承情况:

classPoint3d : virtualpublicPoint {

public:

   Point3d( float x = 0.0, y = 0.0, float z = 0.0 );

   ...

protected:

   float _z;

};

 

编译器会为Point3d合成一个operator=(如果没有的话),合成的operator如下:

inline Point3d& Point3d::operator=( Point3d *constthis, const Point3d &p ) {

   //调用base classoperator=

   this->Point::operator=( p );

 

   // memberwise copy the derived class members

   _z = p._z;

   return *this;

}

 

 

析构语义学 Semantics of Destructor

 

如果class没有定义destructor,则只有class中的member object(或者classbase class)定义了dctor时,编译器才会为class合成一个dctor

 

dctor的扩展:

1.  dctor函数中的user code首先执行。

2.  如果class中有member class object,而这个member class objectdctor,则这些member class objects会以声明顺序的逆序调用各自的dctor

3.  如果object中有vptr,则需要被重新设定,指向适当的base classvtbl

4.  上一层的nontrivial base classdctor会被调用。

5.  如果有任何的virtual base classdctor,而该class是最尾端(most-derived)的class,那么它们会按照原来构造的逆序调用dctor