考虑以下代码:
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.
}
}