请考虑以下代码:
struct Object
{
bool hasComponent(std::string sComponentID);
Component& getComponent(std::string sComponentID);
std::vector<Component*> vComponents;
}
struct System
{
std::vector<Object*> vObjects;
}
我的系统将迭代其向量中的每个Object,并需要从Component的派生成员访问数据(它们都包含系统要使用的不同状态和数据)。 我考虑过这样的事情:
struct NetworkComponent : Component
{
std::string sID;
NetworkComponent(std::string tempID) : sID(tempID) {};
//Network data here
}
for(Object* p : vObjects)
{
if(p->hasComponent("network")
{
NetworkComponent& network = static_cast<NetworkComponent&>(p->getComponent("network");
//Access the data in the structure and do stuff with it.
}
}
然而,这确实感觉非常“hacky”;更不用说不安全了。
我想知道是否有更好的方法来做这样的事情,或者至少如何在将来避免这个问题?
有没有关于这个主题的好文章我可以查阅? 编辑:dynamic_cast不是一个选项,因为它有多慢。
答案 0 :(得分:1)
听起来你正试图重新发明dynamic_cast
答案 1 :(得分:0)
我重构getComponent
方法以返回指针(如果不存在这样的组件,则为nullptr
)而不是引用,并且还使用常量引用传递字符串参数:
Component * getComponent(const std::string & sComponentId);
然后你可以这样做:
template <typename CompType, typename ... Args>
CompType * getComponentOfType(Args && ... args)
{ return dynamic_cast<CompType *>(getComponent(std::forward<Args>(args)...)); }
如果dynamic_cast
不是此处的选项,请使用static_cast
。通过这样做,在这种情况下,您只会失去编程错误的安全层。
做类似的事情:
for(Object * const p : vObjects) {
assert(p);
NetworkComponent * const net =
p->getComponentOfType<NetworkComponent>("network");
if (net) {
// Use the network component.
}
}
答案 2 :(得分:0)
您可以定义class Object
以包含要在派生类中使用的虚拟方法。
他们每个人都应该抛出异常,这意味着这个对象没有重新定义这个方法
当然,在每个派生类中,您应该重新定义它的对象应该具有的方法。