我目前正在制作一个小型游戏引擎,并且遇到了一个我没想到的问题。
我有一个根类,我的引擎中的大多数类派生自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;
}
答案 0 :(得分:5)
我将简化示例来演示问题。你有:
Get-ChildItem ...
<skipped>
} | Select Path,Size,Count | Out-File "files.txt"
您认为这是您的等级制度:
但实际上它看起来像这样:
这应该说明问题。您的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 { }
};
有两个名为D
的纯虚函数(通过其foo
个基础),其中只有一个具有覆盖(通过A
})。通过B
的路径没有覆盖C
,因此foo()
仍被视为抽象。
将结构实际制作为钻石的方法是使用virtual
inheritance:
D
这样只有一个基类struct B : virtual A {
void foo() override { }
};
struct C : virtual A {
virtual void bar() = 0;
};
struct D : B, C {
void bar() override { }
};
类,因此只有一个虚拟A
,因此foo()
中的覆盖就足够了。
答案 1 :(得分:3)
您的SDLTexture继承自CPObject和TextureProtocol,每个都继承自CPObjectProtocol,因此每个SDLTexture中有两个不同的CPObjectProtocol副本,第二个副本有一个指向缺少这些纯虚函数实现的vtable的指针。
你应该阅读&#34;虚拟继承&#34;这将允许您只有一个CPObjectProtocol副本。
由于CPObjectProtocol没有数据,只有方法,显然你的意图是在每个SDLTexture中只有一个副本。