[英]what is a reason for which RTTI is considered as a bad design?
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
行為不屬於您的V
或ABC
類。 因此,您很想使用RTTI(通過typeid
或dynamic_cast
)。 更好的解決方案通常是為類層次結構實現訪問者模式。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.