- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我想重建我的小型 3d 引擎,它非常小,所以我只将所有文件放在一个项目中。现在,我想用接口(interface)重构它,这样我就可以将不同的模块分散到不同的项目中,并将它们构建为一个 dll。当我这样做的时候,我在框架代码的基本设计上遇到了很多困难。我想设计一个我的小引擎的“对象层次结构”,它是在以前的工作中实现的。例如:
Object
Component
SceneComponent
StaticMeshComponent/SkelMeshComponent
D3DSkelComponent
...
但它们是直接实现的。现在,我想使用接口(interface)(纯虚拟类),我已经设计了基本接口(interface)(用于测试):
#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?好吧,这太疯狂了!!!
我认为,这是 abime。这个设计的错误是什么?如何改变设计思路来避免这种困境?您知道一个可以保持这些接口(interface)的继承层次并易于实现的想法吗?如果我使用很多虚拟继承,有没有性能问题?
最佳答案
正如您提到的,您可以通过虚拟继承来解决这个问题。这将在层次结构中仅创建一个多重继承接口(interface)类的实例。
首先是接口(interface):
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 .
关于c++ - 一道C++接口(interface)(纯虚类)/多重继承/虚继承的设计题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12998255/
我有一个特别的问题想要解决,我不确定是否可行,因为我找不到任何信息或正在完成的示例。基本上,我有: class ParentObject {}; class DerivedObject : publi
在我们的项目中,我们配置了虚 URL,以便用户可以在地址栏中输入虚 URL,这会将他们重定向到原始 URL。 例如: 如果用户输入'http://www.abc.com/partner ',它会将它们
我是一名优秀的程序员,十分优秀!