我想要重建我的小型3D引擎,它非常小,所以我只将所有文件放在一个项目中。 现在,我想用接口重建它,所以我可以将不同的模块分散到不同的项目并将它们构建为dll。 当我这样做时,我在框架代码的基本设计中遇到了很多困难。 我想设计一个小型引擎的“对象层次结构”,它是在以前的工作中实现的。例如:
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编写模板类或普通类,例如:
template < typename TBase >
class TObject : public TBase
{
public:
virtual std::string GetName()
{
return m_strTest;
}
std::string m_strTest;
};
基于这个TObject,我可以实现一个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基类,所以我必须将所有“public xxx”更改为“virtual public xxx”,它看起来很糟糕。 另一个问题是CStaticMesh必须实现IStaticMesh的所有虚拟成员函数,包括:
virtual void Draw() = 0;
virtual void BuildSomeMesh() = 0;
即使在CMesh中有一个Draw,它是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;
}
};
看起来好像,但是如何实现CD3DSkeletalMesh?制作一个TSkeletalMesh?好吧,这太疯狂了!!!
我认为,这是不合时宜的。 这个设计中的错误是什么?如何改变设计理念以避免这种困境?你知道一个能够保持这些接口的继承层次并轻松实现的想法吗? 如果我使用许多虚拟继承,是否有任何性能问题?答案 0 :(得分:0)
正如您所提到的,您可以使用虚拟继承解决此问题。这将在层次结构中仅创建一个乘法继承的接口类的一个实例。
首先是接口:
class IObject
{
public:
virtual std::string GetName() = 0;
};
class IMesh : virtual public IObject
{
public:
virtual void Draw() = 0;
};
class IStaticMesh : virtual public IMesh
{
public:
virtual void BuildSomeMesh() = 0;
};
class ISkeletalMesh : virtual public IMesh
{
public:
virtual void PlayAnim( const std::string& strAnimName ) = 0;
};
class ID3DSkeletalMesh : virtual public ISkeletalMesh
{
public:
virtual void LoadD3D( const std::string& strD3D ) = 0;
};
然后实现:
class CObject : virtual public IObject
{
public:
std::string GetName()
{
return m_strTest;
}
std::string m_strTest;
};
class CMesh : public CObject, virtual public IMesh
{
public:
void Draw()
{
cout<<"draw mesh" <<endl;
}
};
class CStaticMesh : public CMesh, virtual public IStaticMesh
{
public:
void BuildSomeMesh()
{
cout<<"Build Some Mesh!"<<endl;
}
};
...
有关此方面的性能影响,请查看this question。