派生类中成员的初始化

作者:jicanmeng

时间:2014年12月03日


派生类中成员包括两种:基类对象和派生类中自身的数据成员(包括class类型的对象成员)。需要说明的是,通常将派生类中的基类,称为基类拷贝,或称为"base class subobject,基类子对象"。

派生类中对象成员的初始化应该在初始化列表中进行。而且,派生类的基类拷贝也应该在初始化列表中进行。如果没有的话,就调用默认的基类的构造函数对基类子对象进行初始化。

派生类中的各成员的初始化次序是:首先是基类拷贝的初始化,然后才是派生类自己的数据成员的初始化。

基类拷贝的初始化的次序与它在初始化列表中的次序无关。如果是多继承,那么基类拷贝的初始化次序取决于派生类声明中指定继承时基类的先后次序。

#include <iostream>
#include <cstring>
using namespace std;

class CPoint
{
public:
    CPoint(int x = 0, int y = 0){
        xPos = x;
        yPos = y;
        cout << "CPoint constructor! xPos=" << xPos << ",yPos=" << yPos << endl;
    }
private:
    int xPos, yPos;
};

class Base
{
public:
    int m_nValue;

    Base(int nValue=0)
        :m_nValue(nValue)
    {
        cout << "Base constructor! nValue=" << nValue << endl;
    }
};

class Derived: public Base
{
public:
    double m_dValue;

    Derived(double dValue=0.0, int nValue=0)
        :m_dValue(dValue),m_point(3,4),Base(nValue)
    {
        cout << "Derived constructor! dValue=" << dValue << endl;
    }
private:
    CPoint m_point;
};

int main()
{
    Derived one(5.5, 2);

    return 0;
}

以下是运行结果:

[jicanmeng@andy tmp]$ ./a.out
				Base constructor! nValue=2
				CPoint constructor! xPos=3,yPos=4
				Derived constructor! dValue=5.5
			[jicanmeng@andy tmp]$

可以看到,先构建了Base基类子对象,然后才是Derived自身的对象成员。

learncpp.com上面是这样描述的:

  1. Memory for cDerived is set aside (enough for both the Base and Derived portions).
  2. The appropriate Derived constructor is called
  3. The Base object is constructed first using the appropriate Base constructor
  4. The initialization list initializes variables
  5. The body of the constructor executes
  6. Control is returned to the caller

参考资料

  1. <<C++实用教程>> 电子工业出版社 郑阿奇 主编 丁有和 编著
  2. The C++ Tutorial:
    http://www.learncpp.com/cpp-tutorial/114-constructors-and-initialization-of-derived-classes/