2012-05-22 136 views
17

我明白爲什麼發生這種情況,但我堅持試圖解決它「純稱爲虛擬方法」 ......這裏是產生錯誤時,我的代碼做什麼(因此,導致崩潰)我的程序退出時...如何解決

pure virtual method called

SomeClass::~SomeClass() 
{ 
    BaseClassObject->SomePureVirtualMethod(this); 
} 

void DerivedClass::SomePureVirtualMethod(SomeClass* obj) 
{ 
    //Do stuff to remove obj from a collection 
} 

我從來沒有new SomeClass來電,但我有一個QList<SomeClass*>我追加SomeClass*對象。該析構函數的SomeClass的目的是告訴DerivedClass從它的QList<SomeClass*>收集刪除的SomeClass一個具體實例。

因此,在一個具體的例子...

BaseClass = Shape

DerivedClass = Triangle

SomeClass = ShapeProperties擁有以Shape

參考所以,我永遠不會有致電new ShapeProperties但我有一個QList<ShapeProperties*>TriangleShapeProperties中的析構函數是告訴Triangle從它的QList<ShapeProperties*>集合中刪除ShapeProperties的特定屬性。

回答

28

通過您的析構函數被調用的時候,繼承類的析構函數已經被調用。在構造函數和析構函數中,對象的動態類型可以被有效地視爲與靜態類型相同。也就是說,當你從構造函數/析構函數中調用虛擬方法時,它並不是被調用的被覆蓋的版本。

如果需要在析構函數處調用SomePureVirtualMethod,那麼您必須在類的析構函數中調用它,在此類中實際定義您想要的方法。

+0

那麼我如何知道在引用的構造函數中調用了哪個'this'實例? – user869525

+0

@ user869525:你可以嘗試改說嗎?我不明白... –

+0

我可能誤解了這個,「如果'SomePureVirtualMethod'需要在析構函數中調用,那麼你必須在類的析構函數中調用它,在那裏實際定義你想要的方法。 「 – user869525

8

當調用在Base類SomeClass的析構函數的virtual方法它調用基類SomeClass的方法(SomePureVirtualMethod()),這是沒有定義純虛方法。因此錯誤。

這是爲什麼發生?
構造函數或析構函數中的this的類型是其構造函數或析構函數被調用的類型,因此動態調度在構造函數和析構函數中不起作用,因爲它可以在所有其他函數中使用。

爲什麼它會崩潰?
由於呼叫從構造或析構純虛函數是一個未定義行爲

C++ 03 10。4/6狀態

「成員函數可以從一個抽象類的構造(或析構函數)被調用;直接或間接地使虛擬呼叫(10.3),以純虛函數爲對象的效果從這樣的構造函數(或析構函數)創建(或銷燬)是未定義的。「

如何避免它?
只要確保不要從構造函數或析構函數調用純虛函數。
除非您瞭解所涉及的動態,否則不要在構造函數或析構函數中調用virtual方法。