C++多态之继承7-多重继承
2015-12-30 10:43
423 查看
之前我们列举的所有例子都是单一的继承--每一个继承类有且只有一个父类。然而,C++提供了多重继承的功能,多重继承使得派生类能从多个父类继承成员。
下面是一个多重继承的列子
多重继承看似是对单一继承的扩展,实际上多重继承存在很多问题,这些问题增加了程序的复杂性以及维护难。让我们看看下面这个例子
针对上面的问题,C++提供了方法来解决:明确的指明调用那个版本的函数。使用如下:
上面的环境还算是比较简单的,如果一个类继承了6个或者更多的基类,那问题将更多。其次,更加严重的问题是:钻石问题,如下面的例子:
class PoweredDevice
{
};
class Scanner: public PoweredDevice
{
};
class Printer: public PoweredDevice
{
};
class Copier: public Scanner, public Printer
{
};
上面的例子中有不少问题,包括Copier是否应该有一个还是两个PoweredDeivce的拷贝,如何解决不同类型的模糊引用。当然大多数问题可以通过指定明确的域来解决,但是最大的问题是它增加了复杂度,使开发时间大大增加。所以在使用多重继承的时候要慎重考虑,不到万不得已的时候,就不要使用。
下面是一个多重继承的列子
#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
{
};
上面的例子中有不少问题,包括Copier是否应该有一个还是两个PoweredDeivce的拷贝,如何解决不同类型的模糊引用。当然大多数问题可以通过指定明确的域来解决,但是最大的问题是它增加了复杂度,使开发时间大大增加。所以在使用多重继承的时候要慎重考虑,不到万不得已的时候,就不要使用。
相关文章推荐
- PostgreSQL教程(三):表的继承和分区表详解
- Lua面向对象之类和继承浅析
- 浅析Ruby中继承和消息的相关知识
- 设计引导--一个鸭子游戏引发的设计理念(多态,继承,抽象,接口,策略者模式)
- C++实现不能被继承的类实例分析
- PHP类的封装与继承详解
- js继承 Base类的源码解析
- Javascript 面向对象 继承
- JavaScript 继承使用分析
- Javascript面向对象编程(二) 构造函数的继承
- javascript面向对象之Javascript 继承
- JavaScript 对象、函数和继承
- 关于JavaScript的面向对象和继承有利新手学习
- JavaScript 继承详解(一)
- JavaScript 继承详解(二)
- javascript继承的六大模式小结
- JavaScript中的原型和继承详解(图文)
- JavaScript中继承用法实例分析
- Javascript中3种实现继承的方法和代码实例
- 通过继承IHttpHandle实现JS插件的组织与管理