天天看点

C++多态之继承7-多重继承

之前我们列举的所有例子都是单一的继承--每一个继承类有且只有一个父类。然而,C++提供了多重继承的功能,多重继承使得派生类能从多个父类继承成员。

下面是一个多重继承的列子

C++多态之继承7-多重继承
#include <string>
class Person
{
private:
    std::string m_strName;
    int m_nAge;
    bool m_bIsMale;
 
public:
    Person(std::string strName, int nAge, bool bIsMale)
        : m_strName(strName), m_nAge(nAge), m_bIsMale(bIsMale)
    {
    }
 
    std::string GetName() { return m_strName; }
    int GetAge() { return m_nAge; }
    bool IsMale() { return m_bIsMale; }
};
 
class Employee
{
private:
    std::string m_strEmployer;
    double m_dWage;
 
public:
    Employee(std::string strEmployer, double dWage)
        : m_strEmployer(strEmployer), m_dWage(dWage)
    {
    }
 
    std::string GetEmployer() { return m_strEmployer; }
    double GetWage() { return m_dWage; }
};
 
// Teacher publicly inherits Person and Employee
class Teacher: public Person, public Employee
{
private:
     int m_nTeachesGrade;
 
public:
    Teacher(std::string strName, int nAge, bool bIsMale, std::string strEmployer, double dWage, int nTeachesGrade)
        : Person(strName, nAge, bIsMale), Employee(strEmployer, dWage), m_nTeachesGrade(nTeachesGrade)
    {
    }
};
           

多重继承的问题

多重继承看似是对单一继承的扩展,实际上多重继承存在很多问题,这些问题增加了程序的复杂性以及维护难。让我们看看下面这个例子

class USBDevice
{
private:
    long m_lID;
 
public:
    USBDevice(long lID)
        : m_lID(lID)
    {
    }
 
    long GetID() { return m_lID; }
};
 
class NetworkDevice
{
private:
    long m_lID;
 
public:
    NetworkDevice(long lID)
        : m_lID(lID)
    {
    }
 
    long GetID() { return m_lID; }
};
 
class WirelessAdaptor: public USBDevice, public NetworkDevice
{
public:
    WirelessAdaptor(long lUSBID, long lNetworkID)
        : USBDevice(lUSBID), NetworkDevice(lNetworkID)
    {
    }
};
 
int main()
{
    WirelessAdaptor c54G(5442, 181742);
    cout << c54G.GetID(); // Which GetID() do we call?
 
    return 0;
}
           

程序中存在的问题是对象c54G包含两个GetID()函数,一个是继承自USBDeivce,另外一个继承自NetworkDevice。因此对这个函数的调用时含糊不清的,编译器会给出错误提示。

针对上面的问题,C++提供了方法来解决:明确的指明调用那个版本的函数。使用如下:

int main()
{
    WirelessAdaptor c54G(5442, 181742);
    cout << c54G.USBDevice::GetID();
 
    return 0;
}
           

上面的环境还算是比较简单的,如果一个类继承了6个或者更多的基类,那问题将更多。其次,更加严重的问题是:钻石问题,如下面的例子:

class PoweredDevice
{
};
 
class Scanner: public PoweredDevice
{
};
 
class Printer: public PoweredDevice
{
};
 
class Copier: public Scanner, public Printer
{
};
           
C++多态之继承7-多重继承

上面的例子中有不少问题,包括Copier是否应该有一个还是两个PoweredDeivce的拷贝,如何解决不同类型的模糊引用。当然大多数问题可以通过指定明确的域来解决,但是最大的问题是它增加了复杂度,使开发时间大大增加。所以在使用多重继承的时候要慎重考虑,不到万不得已的时候,就不要使用。

继续阅读