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

what is a reason for which RTTI is considered as a bad design?

本文关键字:是什么 RTTI 认为是      更新时间:2023-10-16

RTTI被认为是糟糕设计的原因是什么
Stroustrup在他的书TC++PL中写道,使用RTTI技术最常见的情况是切换指令,当人们想根据传递对象的"真实"类型来决定应该执行什么代码时。给出了一个例子,其中形状类的对象被传递给函数,并根据形状是圆形、方形、三角形等执行不同的操作。

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() );
}

现在,如果我们添加一个同样从V派生的新类C并调用do_something( C() )(不更改do_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_something(),我们将得到对A::do_something()的调用。

因此,这是虚拟函数优先于RTTI的主要原因。然而,有时您可能会觉得do_something的行为不属于您的VA B C类。因此,您可能会倾向于使用RTTI(通过typeiddynamic_cast)。更好的解决方案通常是实现类层次结构的访问者模式。