C++ RTTI被认为是糟糕设计的原因是什么?
RTTI被认为是糟糕设计的原因是什么?C++ RTTI被认为是糟糕设计的原因是什么?,c++,C++,RTTI被认为是糟糕设计的原因是什么? Stroustrup在他的书TC++PL中写道,使用RTTI技术最常见的情况是使用switch指令,即根据传递对象的“真实”类型来决定应该执行什么代码。给出了一个示例,其中shape类的对象被传递给函数,并根据形状是圆、正方形、三角形、,等等。他写道,这种构造是一种迹象,表明应该用虚拟函数替换开关盒序列。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”。因此,迟早会发现缺少的实现,并且您将立即知道缺少的地方。