为什么在这里使用static_cast而不是dynamic_cast?

q09*_*987 3 c++

我从"更有效的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在这种情况下是否正确地完成了工作?

ild*_*arn 7

为了记录,这是这样做的惯用方法:

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的 指针"的rvalue D,其中D是一个派生自的类B,如果是从"指针D"到"指针"的有效标准转换到B"的存在,CV2是相同的CV-资格,或更大的CV-资格比,CV1,并且B不是虚拟基类D.空指针值将转换为目标类型的空指针值.如果类型的右值"指针CV1 B "指向一个B实际上是类型的对象的子对象D,将得到的指针指向类型的包围对象D.否则,演员的结果是不确定的.