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)
我将简化示例来演示问题.你有:
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就足够了.
| 归档时间: |
|
| 查看次数: |
177 次 |
| 最近记录: |