考虑以下代码:

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不是一个选项。

最佳答案

我将重构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.
    }
}

10-06 02:41