我想重建我的小型3D引擎,它非常小,因此我只將所有文件放在一個項目中。 現在,我想用接口重構它,所以我可以將不同的模塊分散到不同的項目中,並將它們構建爲一個dll。當我這樣做時,我在框架代碼的基本設計中遇到了很多困難。 我想設計一個我的小型引擎的「對象層次結構」,它是在以前的工作中實現的。例如:關於C++接口(純虛擬類)/多繼承/虛繼承的設計問題
Object
Component
SceneComponent
StaticMeshComponent/SkelMeshComponent
D3DSkelComponent
...
但它們直接實施。 現在,我想使用接口(純虛類),我設計的基本接口(用於測試):
#include <cstdio>
#include <iostream>
#include <string>
using namespace std;
class IObject
{
public:
virtual std::string GetName() = 0;
};
class IMesh : public IObject
{
public:
virtual void Draw() = 0;
};
class IStaticMesh : public IMesh
{
public:
virtual void BuildSomeMesh() = 0;
};
class ISkeletalMesh : public IMesh
{
public:
virtual void PlayAnim(const std::string& strAnimName) = 0;
};
class ID3DSkeletalMesh : public ISkeletalMesh
{
public:
virtual void LoadD3D(const std::string& strD3D) = 0;
};
看起來正常,但是當我試圖實現他們,我覺得這可能是一個不可能的使命。 首先,我可以寫一個模板類或正常類IObject提取,如:在此基礎上TObject的
template < typename TBase >
class TObject : public TBase
{
public:
virtual std::string GetName()
{
return m_strTest;
}
std::string m_strTest;
};
,我可以實現CMesh:
class CMesh : public TObject<IMesh>
{
public:
virtual void Draw()
{
cout<<"draw mesh" <<endl;
}
};
IMesh* pMesh = new CMesh(); // ok
IObject* pObj = pMesh; // ok
到目前爲止,它工作得很好。但如何實現CStaticMesh/CSkeletalMesh/CD3DSkeletalMesh? 它也許是這樣的:
class CStaticMesh : public CMesh, public IStaticMesh
{
public:
};
,但我有兩個IObject提取的基類,所以我必須改變所有的「公共XXX」到「虛擬公共XXX」,這很糟糕。 另一個問題是CStaticMesh必須實現IStaticMesh的所有虛擬成員函數,包括:
virtual void Draw() = 0;
virtual void BuildSomeMesh() = 0;
即使在CMesh平局是CStaticMesh的鹼基響應。 好吧,也許我需要一個TMesh:
template < typename TBase >
class TMesh : public TObject<TBase>
{
public:
virtual void Draw()
{
cout<<"draw mesh" <<endl;
}
};
像這樣實施CStaticMesh:
class CStaticMesh : public TMesh<IStaticMesh>
{
public:
virtual void BuildSomeMesh()
{
cout<<"Build Some Mesh!"<<endl;
}
};
看起來不錯,但如何implment CD3DSkeletalMesh?做一個TSkeletalMesh?好的,這太瘋狂了!
我想,這是abime。 這是這個設計中的錯誤嗎?如何改變設計理念以避免這種困境?你知道一個可以保持這些接口的繼承層次並輕鬆實現的想法嗎?如果我使用許多虛擬繼承,有沒有什麼性能isuue?