我从"更有效的C++"一书中复制了以下文本.
第31项:使函数虚拟化为多个对象.
class GameObject { ... };
class SpaceShip: public GameObject { ... };
class SpaceStation: public GameObject { ... };
class Asteroid: public GameObject { ... };
Run Code Online (Sandbox Code Playgroud)
最常见的双重调度方法通过if-then-elses链将我们带回到虚拟函数仿真的无情世界.在这个苛刻的世界中,我们首先发现了otherObject的真实类型,然后我们针对所有可能性测试它:
void SpaceShip::collide(GameObject& otherObject)
{
const type_info& objectType = typeid(otherObject);
if (objectType == typeid(SpaceShip)) {
SpaceShip& ss = static_cast<SpaceShip&>(otherObject);
process a SpaceShip-SpaceShip collision;
}
else if (objectType == typeid(SpaceStation)) {
SpaceStation& ss =
static_cast<SpaceStation&>(otherObject);
process a SpaceShip-SpaceStation collision;
}
...
}
Run Code Online (Sandbox Code Playgroud)
这是一个问题:
Q1>为什么我们在这里使用static_cast而不是明显的dynamic_cast?
Q2>在这种情况下它们是否相同?
谢谢
// 更新 //
事实上,我对问题2更感兴趣.
例如,
class base {};
class subclass : public base {};
base *pSubClass = new subclass;
subclass *pSubClass1 = static_cast<subClass*> (pSubClass);
Run Code Online (Sandbox Code Playgroud)
//虽然我知道我们应该在这里使用dynamic_cast,但是static_cast在这种情况下是否正确地完成了工作?
为了记录,这是这样做的惯用方法:
void SpaceShip::collide(GameObject& otherObject)
{
if (SpaceShip* ss = dynamic_cast<SpaceShip*>(&otherObject)) {
// process a SpaceShip-SpaceShip collision;
}
else if (SpaceStation* ss = dynamic_cast<SpaceStation*>(&otherObject)) {
// process a SpaceShip-SpaceStation collision;
}
// ...
}
Run Code Online (Sandbox Code Playgroud)
它更短,表现出相同的性能特征,而且最重要的是,惯用的C++不会让其他程序员抓住他们的头脑并想知道重点是什么.
编辑(响应OP的编辑):
是的,这是明确定义的行为.这是C++ 03标准所说的§5.2.9/ 8:
类型为" cv1的 指针"的rvalue
B,其中B是一个类类型,可以转换为类型为"指向cv2的 指针"的rvalueD,其中D是一个派生自的类B,如果是从"指针D"到"指针"的有效标准转换到B"的存在,CV2是相同的CV-资格,或更大的CV-资格比,CV1,并且B不是虚拟基类D.空指针值将转换为目标类型的空指针值.如果类型的右值"指针CV1B"指向一个B实际上是类型的对象的子对象D,将得到的指针指向类型的包围对象D.否则,演员的结果是不确定的.
| 归档时间: |
|
| 查看次数: |
1978 次 |
| 最近记录: |