多继承

作者:jicanmeng

时间:2014年12月04日


多继承就是一个派生类同时继承了两个基类的属性和方法。

看一个例子:

#include <iostream>
using namespace std;

class USBDevice
{
private:
    long m_lID;

public:
    USBDevice(long lID)
        : m_lID(lID)
    {
        cout << "USBDevice constructor" << endl;
    }

    long GetID() { return m_lID; }
};

class NetworkDevice
{
private:
    long m_lID;

public:
    NetworkDevice(long lID)
        : m_lID(lID)
    {
        cout << "NetworkDevice constructor" << endl;
    }

    long GetID() { return m_lID; }
};

class WirelessAdaptor: public USBDevice, public NetworkDevice
{
public:
    WirelessAdaptor(long lUSBID, long lNetworkID)
        : NetworkDevice(lNetworkID), USBDevice(lUSBID)
    {
        cout << "WirelessAdaptor constructor" << endl;
    }
};

int main()
{
    WirelessAdaptor c54G(5442, 181742);
//    cout << c54G.GetID(); // Which GetID() do we call?
    cout << c54G.USBDevice::GetID();
    cout << c54G.NetworkDevice::GetID();

    return 0;
}

以下是运行结果:

[jicanmeng@andy tmp]$ ./a.out
				USBDevice constructor
				NetworkDevice constructor
				WirelessAdaptor constructor
			[jicanmeng@andy tmp]$

对于这个例子,需要注意两点:

  1. 可以看到,两个基类中都有一个GetID()方法,如果在派生类中直接调用GetID,如上面47行所示,那么会编译出错,因为编译器不知道要调用哪一个基类的GetID()函数。需要详细指定才可以,如48行和49行所示。
  2. WirelessAdaptor类继承了两个基类,那么在构造WirelessAdaptor时,需要先构造哪一个基类子对象呢?其实在3.6.1 派生类中成员的初始化中已经提到:如果是多继承,那么基类拷贝的初始化次序取决于派生类声明中指定继承时基类的先后次序。 。我们在WirelessAdaptor类声明的时候(34行),基类的先后次序是USBDevice类在前,NetworkDevice类在后。所以会先构造USBDevice基类子对象,然后再构造NetworkDevice基类子对象。

多继承使用起来容易出错。learncpp.com上面建议大家使用的时候要非常小心。其它语言对多继承的使用或多或少有一些限制。(Many object-oriented languages (eg. Smalltalk, PHP) do not even support multiple inheritance. Many relatively modern languages such as Java and C# restricts classes to single inheritance of normal classes, but allow multiple inheritance of interface classes (which we will talk about later). )

参考资料

  1. <<C++实用教程>> 电子工业出版社 郑阿奇 主编 丁有和 编著
  2. The C++ Tutorial:
    http://www.learncpp.com/cpp-tutorial/117-multiple-inheritance/