如果我已经检查了 typeid,为什么不使用 static_cast 而不是 dynamic_cast?

问题描述

下面的代码检查来自 p 指针的对象是否来自类型 Student,如果是这种情况,则执行 dynamic_cast

但是为什么我们不能做一个 static_cast 呢?

我认为转换是安全的,因为我们检查了来自指针的对象是否来自正确的类型,并且 static_cast 更快。​​

void testRTTI (Persoon ∗p){
if (strstr (type id (∗p).name(),"Student")!=NULL){
Student ∗ s = dynamic_cast<Student ∗>(p) ;
s−>studeer();
}
else p−>doe();
}

解决方法

您可以删除 typeid 检查,并且只检查 dynamic_cast 是否返回 nullptr

void testRTTI (Persoon *p){
  if (Student * s = dynamic_cast<Student *>(p); s != nullptr){
    s->studeer();
  } else {
    p->doe();
  }
}

我认为您对动态转换指针的作用有误解。对于 dynamic_cast<T*>,它将首先检查传递给 dynamic_cast<T*> 的指针是否可以以有效方式转换为 T*。这个测试并不比你的 typeid(*p).name() 贵(至少对于给定的情况不是),而且肯定比 strstr(typeid(*p).name(),"Student")!=NULL 便宜。

如果它不能转换为 T* 它将返回 nullptr 如果它可以转换它将返回相同的指针转换为 T* 这不需要是一个操作完全没有。

因此您的代码会进行两项检查,一项检查您的 typeid,另一项检查 dynamic_cast

,
if (strstr(typeid (∗p).name(),"Student")!=NULL)

在两个方面存在缺陷。

  1. 函数 name() 返回一个实现定义的值,没有任何保证。该值可能会从一次运行更改为另一次运行,并且可能是一个随机字符串。

  2. 忽略第一个问题:如果您有另一个类,其中 typeid(...).name() 将返回一个也包含 "Student" 的字符串怎么办?


这就是您拥有 dynamic_cast 的原因:

Student ∗ maybeAStudent = dynamic_cast<Student ∗>(p);

if(maybeAStudent != nullptr)
{ /* p is a Student,do student things*/ }
else 
{ /* p is another Person,do person things */}

注意:dynamic_cast 仅在 Person 至少有一个虚函数时有效。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...