RTTI被认为是不良设计的原因是什么?
Stroustrup在他的TC++ PL书中写道,使用RTTI技术最常见的情况是与切换指令一起使用,这时人们想根据传递的对象的“真实”类型决定执行什么代码。举一个例子,其中将一个形状类的对象传递给该函数,并根据形状是圆形,正方形,三角形等来执行不同的 Action 。他写道,这种构造是一个应该替换的标志。通过虚拟功能切换情况的顺序。
最佳答案
仅当您的类具有虚拟表时,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();
}
现在,如果我们从
C
派生V
而不执行C::do_something()
,则会出现编译时错误。如果我们从D
派生A
,而又不冒失D::do_something()
,我们将得到A::do_something()
的调用。因此,这是虚拟功能优于RTTI的主要原因。但是有时您可能会觉得
do_something
的行为不属于您的V
或A B C
类。因此,您很想使用RTTI(通过typeid
或dynamic_cast
)。更好的解决方案通常是为类层次结构实现访问者模式。关于c++ - RTTI被认为是不良设计的原因是什么?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12102569/