C++ 动态检查使用可变继承的类的类型的最佳方法是什么?
我正在为2D游戏引擎编写一个实体组件系统,该引擎使用可变模板构建游戏对象。下面是对象类,它只是所有组件的容器。我去掉了不相关的东西C++ 动态检查使用可变继承的类的类型的最佳方法是什么?,c++,templates,variadic-templates,C++,Templates,Variadic Templates,我正在为2D游戏引擎编写一个实体组件系统,该引擎使用可变模板构建游戏对象。下面是对象类,它只是所有组件的容器。我去掉了不相关的东西 template<class ... Components> class Object : public Components...{ public: Object(Game* game) : Components(game)...{ } }; 模板 类对象:公共组件{ 公众: 对象(游戏*游戏):组件(游戏){ } }; 这些组件
template<class ... Components>
class Object : public Components...{
public:
Object(Game* game) : Components(game)...{
}
};
模板
类对象:公共组件{
公众:
对象(游戏*游戏):组件(游戏){
}
};
这些组件由对象继承,但我正在尝试找到检查这些组件类型的最佳方法,以便它们能够正确地相互通信。例如,物理组件将包含对象的更新位置。可绘制组件需要获得该位置,以便可以在世界上正确的位置绘制。我想向对象添加一个更新函数,用于更新每个组件,并在当前组件之间传输任何可以/需要传输的信息。多态性就是您想要的。 只需将所有组件制作成这样:
public Object
{
enum TYPE{
COMPONENT,,
GAMEOBJECT,
ETC,,,
};
Object(TYPE id){m_id = id;}
protected:
TYPE m_id;
virtual void Update(void) = 0;
virtual void Render(void) = 0;
public:
void GetTypeOf(void)const{return m_id;}
};
class Component : Object
{
enum COMPONENT_TYPE
{
COLLIDER,
RENDERER,
ETC,,,,
};
Component() : Object (COMPONENT){/**/}
virtual void Update(void){return;}
virtual void Render(void){return;}
};
class BoxCollider : Component
{
BoxCollider(void) : Component(BOXCOLLIDER){/**/}
void Update(void)
{
//to do
}
void Render(void)
{
//to do
}
};
然后,您可以简单地拥有Object*或Component*的数据结构
您可以通过这种方式进行迭代:
std::vector<Component*>::iterator components = ComponentVector.begin();
for(;components != ComponentVector.end() ; ++components)
{
*(component)->Update();
*(component)->Render();
std::cout << "id" << *component->getTypeOf() << std::endl;
}
std::vector::iterator components=ComponentVector.begin();
对于(;组件!=ComponentVector.end();++components)
{
*(组件)->Update();
*(组件)->Render();
std::cout对象
类继承自其所有组件,这意味着实际上它是其所有组件。您可以使用此信息来设计
更新方法。
例如:
#include <cassert>
struct Game { };
struct Physics {
int position{0};
Physics(Game *) { }
void update(void *) { }
};
struct Drawable {
Drawable(Game *) { }
void update(Physics *physics) {
physics->position = 42;
}
};
template<class ... Components>
class Object: public Components... {
public:
Object(Game* game) : Components(game)... { }
void update() {
int a[] = { (Components::update(this), 0)... };
}
};
int main() {
Game game;
Object<Physics, Drawable> object{&game};
assert(object.position == 0);
object.update();
assert(object.position == 42);
}
#包括
结构博弈{};
结构物理学{
int位置{0};
物理(游戏*){}
无效更新(无效*){}
};
结构可拉伸{
可抽签(游戏*){}
void更新(物理*物理){
物理->位置=42;
}
};
模板
类对象:公共组件{
公众:
对象(游戏*游戏):组件(游戏){}
无效更新(){
inta[]={(组件::更新(this),0)…};
}
};
int main(){
游戏;
对象{&game};
断言(object.position==0);
update();
断言(object.position==42);
}
在这里,当调用其update
方法时,您可以看到asDrawable
接收Physics
。
此解决方案的缺点是:
- 组件的
update
方法必须获得指针参数,即使它们不需要引用任何其他组件
- 如果存在一个需要引用多个组件的组件,则必须获取两个或多个指针作为
update
方法的参数,或者强制转换void*
你能澄清一下你的需求吗,比如说用更多的代码吗?我可能遗漏了一些东西,因为如果你只是需要绘图组件来使用物理上的协调,只要写一些类似于void Object::update(){this->draw(*this);}
,假设你有void Drawable::draw(const physics&)
。只要右可绘制的和物理位于可变组件中,这将立即起作用…