使用static_cast处理混合(基础和派生)对象的向量是否存在性能风险?(又名"这是一个愚蠢的想法?")

ilz*_*zxc 7 c++ vector static-cast

给定一个基类gameObject和派生类animatedGameObject,我认为将所有实例存储在一个中可能是好的std::vector.如果向量GameObjects被声明为基类型gameObject*,则派生对象实例需要强制转换.

例:

vector<gameObject*> GameObjects;

gameObject A* = new gameObject( ...init... ); 
animatedGameObject B* = new animatedGameObject( ...init... );

GameObjects.push_back(A);
GameObjects.push_back(B);

// to access the animatedGameObject functions:
static_cast<animatedGameObject*>(GameObjects[1])->functionUniqueToAnimated();
Run Code Online (Sandbox Code Playgroud)

像往常一样害怕,我转向Scott Meyers(Effective C++,3rd Edition),他写了这个主题:

许多程序员认为演员表什么都不做,只是告诉编译器将一种类型视为另一种类型,但这是错误的.任何类型的转换(通过强制转换显式或由编译器隐式)通常会导致在运行时执行的代码.

我已经阅读了他的第27项:最小化铸造两次,但鉴于我对此缺乏经验,我正在努力解决一个简单的问题"这是一个难以理解的事情吗?"

我应该指出,有几个原因,这一个愚蠢的事什么都没有做与调用static_cast.按重要性排列的问题是:

  1. static_cast在上面的示例中没有看到使用可能存在的风险吗?
  2. 是否有比std::vector这些方法更好的数据结构?(只有当有一个显而易见的时候,我才会要求你为我做研究.)

这是我第一次在这里提问,所以必要时提前道歉.

Pot*_*ter 7

static_cast不是正确的工具,除非你知道指针指向一个animatedGameObject而不是一个gameObject.您使用什么数据结构来存储该信息?

在基指针是动态调度或作业之后确定派生对象的类型dynamic_cast.在您的示例中,调用GameObjects[1]->draw()应该不使用强制转换,因为它draw应该是虚函数.否则,您可以使用dynamic_cast< animatedGameObject & >( * GameObjects[1] )断言该对象是animatedGameObject,std::bad_cast如果不是则抛出异常.(这仍然需要一个virtual函数class gameObject,通常是它的析构函数.)

static_cast对多态衍生类型做的是代码气味.


你也问std::vector这个用例是否是一个好的数据结构.它是,但不是"裸"指针的矢量.C++ 11现在提供"智能指针"内存管理类,其执行newdelete对你来说,渲染实际经营者所有,但已经过时.考虑std::unique_ptr这种情况.