用继承的类实现继承的抽象(纯虚拟)类?

amy*_*bit 3 c++ inheritance multiple-inheritance abstract

我目前正在制作一个小型游戏引擎,并且遇到了一个我没想到的问题.

我有一个根类,我的引擎中的大多数类派生自,CPObject.CPObject符合CPObjectProtocol,定义一些纯虚函数的抽象类.

我创建了另一个协议,TextureProtocol以及它的具体实现SDLTexture,它也继承自CPObject.到目前为止,一切正常,我可以创建SDLTexture的实例.但是,如果我TextureProtocol继承CPObjectProtocol,clang告诉我,我无法创建抽象类的实例.

我假设一个类可以通过继承另一个类的实现来实现接口.我错了吗?

// CPObject abstract interface/protocol
class CPObjectProtocol {
public:

    virtual void retain() = 0;
    virtual void release() = 0;
    //more methods like this
};

// CPObject implementation.
class CPObject : public CPObjectProtocol {
public:

    CPObject() { _retainCount = 0; }
    virtual ~CPObject() { }

    // implementation of CPObjectProtocol
    virtual void retain() { _retain++; }
    virtual void release() {
        if(--_retainCount <= 0) {delete this;}
    }
private:
    int _retainCount;
};


// Texture absract interface/protocol
// inherits from CPObjectProtocol so that retain() and release()
// can be called on pointers to TextureProtocol (allowing for
// implementations to be swapped later)
class TextureProtocol : public CPObjectProtocol {

public:
    virtual Color getColor() = 0;
};

// An implementation of TextureProtocol
// I assumed it would fulfil CPObjectProtocol by inheriting
// from CPObject's implementation?
class SDLTexture : public CPObject, public TextureProtocol {
public:
    SDLTexture() { _id = 0; }
    virtual ~SDLTexture { }

    // implementation of TextureProtocol
    virtual int getID() { return _id; }

private:
    int _id;
}
Run Code Online (Sandbox Code Playgroud)

Bar*_*rry 6

我将简化示例来演示问题.你有:

struct A {
    virtual void foo() = 0;  
};

struct B : A {
    void foo() override { }  
};

struct C : A {
    virtual void bar() = 0;    
};

struct D : B, C {
    void bar() override { }  
};
Run Code Online (Sandbox Code Playgroud)

你认为这是你的层次结构:

在此输入图像描述

但实际上它看起来像这样:

在此输入图像描述

这应该说明问题.你D有两个名为纯虚函数foo(通过两个公司的A基地),只有其中一个具有覆盖(通过B).路径via C没有覆盖foo(),因此D仍然被认为是抽象的.

将结构实际制作为钻石的方法是使用virtual继承:

struct B : virtual A {
    void foo() override { }  
};

struct C : virtual A {
    virtual void bar() = 0;    
};

struct D : B, C {
    void bar() override { }  
};
Run Code Online (Sandbox Code Playgroud)

这种方式只有一个基A类,因此只有一个虚拟foo(),所以覆盖B就足够了.