C++纯虚拟多重继承

C++ pure virtual multiple inheritance?

本文关键字:多重继承 虚拟 C++      更新时间:2023-10-16

我需要一个使用接口多重继承的实现的帮助。。。

有一个现有的代码有一个接口,它有很多功能。实例是使用工厂创建的。

class IBig
{
    // Lot of pure virtual functions
};

以及他的实现:

class CBig: public IBig
{
    // Implementation
}

我想将接口拆分为多个较小的接口,但它应该在一段时间内与现有代码保持兼容。

以下是我尝试做的一个示例:

class IBaseA
{
public:
    virtual void DoA() = 0;
};
class IBaseB
{
public:
    virtual void DoB() = 0;
};
// The same interface, now based on multiple smaller interfaces
class IBig : public IBaseA, public IBaseB
{
};
class CBaseA: public IBaseA
{
public:
    virtual void DoA()
    {
        printf("DoAn");
    }
};
class CBaseB: public IBaseB
{
public:
    virtual void DoB()
    {
        printf("DoBn");
    }
};
// Inherit from base classes where the implementation is, and from IBig as 
// the instance of CBig is returned as IBig.
class CBig: public CBaseA, public CBaseB, public IBig
{
};

这里的问题是类CBig无法实例化。编译器表示,函数DoA和DoB是纯虚拟的,即使它们是在CBaseA和CBaseB中实现的。如果我不想再次实现函数,只想调用基类的函数,该怎么办?

注意:我知道设计很难看,但这只是暂时的,直到大接口可以被替换,而且。。。。我想了解!;-)

提前感谢!

这里应该使用虚拟继承。这个特性确保在实例化子类时,实际上继承的基类只有一个实例。对于您的示例,这看起来像:

#include <cstdio>
class IBaseA
{
public:
    virtual void DoA() = 0;
};
class IBaseB
{
public:
    virtual void DoB() = 0;
};
// The same interface, now based on multiple smaller interfaces
class IBig : virtual public IBaseA,  virtual public IBaseB
//              ^                       ^
{
};
class CBaseA: virtual public IBaseA
//              ^
{
public:
    virtual void DoA()
    {
        printf("DoAn");
    }
};
class CBaseB: virtual public IBaseB
//              ^
{
public:
    virtual void DoB()
    {
        printf("DoBn");
    }
};
// Inherit from base classes where the implementation is, and from IBig as 
// the instance of CBig is returned as IBig.
class CBig: public CBaseA, public CBaseB, public IBig
{
};
int main()
{
    CBig cb;
}

以上更改确保在多次从IBaseAIBaseB继承时不会创建DoADoB的额外声明。

这被称为致命的死亡钻石(或简单的钻石问题)。之所以会出现这种情况,是因为CBig继承自共享公共基类的类。

您可以通过在DoA前面加上它属于的类来调用正确的DoA

CBaseA::doA();

或者您使用虚拟继承只拥有IBaseA和IBaseB 的一个实例

class CBaseA : public virtual IBaseA {};
class CBaseB : public virtual IBaseB {};
class IBig : public virtual IBaseA, public virtual IBaseB {};

等等…