2008年11月22日 星期六

'dynamic_cast' : 'A' is not a polymorphic type


class A
{
public:
A() : m_a(1) {}

int m_a;
}

class B : public A
{
public:
B() : A(), m_b(2) {}

int m_b;
}

int main()
{
A* a = new B;
B* b = dynamic_cast(a); // error
delete a;
}


上面的程式碼在編譯時,我們最好的朋友 - complier - 會告訴你dynamic_cast那一行有錯誤,錯誤訊息應該會像下面這樣:
'dynamic_cast' : 'A' is not a polymorphic type
咦,明明B和A是有繼承體系的,為什麼沒辦法用dynamic_cast呢??
主要是dynamic_cast在做型別轉換時會依賴vftable做型別檢查
(dynamic_cast會檢查型別是否符合,不符合會傳回NULL)
而要建立vftable只要在class底下有包含至少一個virtual function就可以了
在effective C++也有提到,如果你的類別需要被繼承的話,最好將你的解構子(destructor)設為virtual
既可以加入vftable,也可以避免delete base的memory leak

所以程式碼修改成下面就ok了

class A
{
public:
A() : m_a(1) {}
virtual ~A() {}

int m_a;
}

class B : public A
{
public:
B() : A(), m_b(2) {}
virtual ~B() {}

int m_b;
}

int main()
{
A* a = new B;
B* b = dynamic_cast(a); // pass
delete a;
}


4 則留言:

fr3@K 提到...

請參考 這篇文字 底下的對話

高橋旺 提到...

Thank you.. :)
其實這個東西以前都只會用,也沒去研究他dynamic_cast怎麼判斷的,而且我都很習慣的在base class加入virtual destructor,所以剛好都沒遇到這個問題 XD

fr3@K 提到...

我寫在 COdE fr3@K 的回應.

高橋旺 提到...

這邊有一些補充

LinkWithin

Related Posts with Thumbnails