C++ RTTI被认为是糟糕设计的原因是什么?

C++ RTTI被认为是糟糕设计的原因是什么?,c++,C++,RTTI被认为是糟糕设计的原因是什么? Stroustrup在他的书TC++PL中写道,使用RTTI技术最常见的情况是使用switch指令,即根据传递对象的“真实”类型来决定应该执行什么代码。给出了一个示例,其中shape类的对象被传递给函数,并根据形状是圆、正方形、三角形、,等等。他写道,这种构造是一种迹象,表明应该用虚拟函数替换开关盒序列。RTTI仅在类具有虚拟表的情况下有效。如果您有一个虚拟表,则可以实现虚拟函数。应该在对象类型的开关上使用虚拟函数的原因是,它可以更好地处理继承链,并且在添

RTTI被认为是糟糕设计的原因是什么?

Stroustrup在他的书TC++PL中写道,使用RTTI技术最常见的情况是使用switch指令,即根据传递对象的“真实”类型来决定应该执行什么代码。给出了一个示例,其中shape类的对象被传递给函数,并根据形状是圆、正方形、三角形、,等等。他写道,这种构造是一种迹象,表明应该用虚拟函数替换开关盒序列。

RTTI仅在类具有虚拟表的情况下有效。如果您有一个虚拟表,则可以实现虚拟函数。应该在对象类型的开关上使用虚拟函数的原因是,它可以更好地处理继承链,并且在添加新类时不那么脆弱

例如:

class A : public V {}
class B : public V{}

void do_something( const V & v )
{
  if (typeid(A) == typeid(v)) { .. its an A .. }
  if (typeid(B) == typeid(v)) { .. its a B .. }
}

int main()
{
   do_something( A() ); 
   do_something( B() );
}
现在,如果我们添加一个新类
C
,该类也是从
V
派生的,并调用
dou something(C())
(不更改
dou something
的实现),则不会发生任何事情。(编译时没有错误)。如果我们添加一个从
a
派生的类
D
,也不会出现错误,也不会发生任何事情

将此与虚拟函数的行为进行对比

struct V 
{
   virtual void do_something() const =0;
};

struct A
{
  virtual void do_something() const { ... its an A ... }
}

struct B
{
  virtual void do_somethine() const { ... its a B ... }
}

void do_something( const V & v )
{
  v.do_something();
}
现在,如果我们从
V
派生
C
,而不实现
C::do_something()
,我们将得到一个编译时错误。如果我们从
A
派生
D
,并且不执行
D::do\u something()
我们将得到对
A::do\u something()
的调用


因此,这是虚拟函数优于RTTI的主要原因。然而,有时您可能会觉得
做某事的行为不属于您的
V
A B C
类。因此,您可能会尝试使用RTTI(通过
typeid
dynamic\u cast
)。更好的解决方案通常是为类层次结构实现访问者模式。

Dupe?看这个:这完全不是一个骗局。注意,我故意使用虚拟析构函数。我并没有解释说,如果它只被用作其他类的基类,那么
C
不需要实现它的纯虚拟函数。虽然用虚拟方法替换if链的基本思想是正确的,但是if链可以通过将其写成if(…)else if(…){…}else if(…){…}else断言来改进(false);获取运行时错误而不是“nothing”。因此,迟早会发现缺少的实现,并且您将立即知道缺少的地方。