1

RTTI 被认为是一个糟糕的设计的原因是什么?
Stroustrup 在他的 TC++PL 一书中写道,RTTI 技术最常见的使用案例是使用 switch 指令,当人们想要根据传递对象的“真实”类型来决定应该执行什么代码时。给出了一个例子,其中一个形状类的对象被传递给函数,并根据形状是圆形、方形、三角形等执行不同的动作。他写道,这种构造是一个应该替换的标志虚函数的 switch-case 序列。

4

1 回答 1

2

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并调用do_something( C() )(不改变 的实现do_something),什么都不会发生。(编译时没有错误)。如果我们添加一个D派生自的类A也没有错误并且什么也没有发生。

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

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

现在,如果我们派生CV而不实现C::do_something(),我们将得到一个编译时错误。如果我们派生DA而不是实现D::do_something(),我们将收到对A::do_something().

所以这是虚拟函数比 RTTI 更受欢迎的主要原因。但是,有时您可能会觉得 的do_something行为不属于您的VA B C类。因此,您会很想使用 RTTI(通过typeiddynamic_cast)。更好的解决方案通常是实现类层次结构的访问者模式。

于 2012-08-24T03:58:37.890 回答