Pure virtual function call error探討

來源:互聯網
上載者:User

在實習的單位搞CxImage庫時不知為什麼在Debug時沒有問題,但是Release版裡竟然跳出個Pure virtual function call error! 啥東西呀,竟然遇上了,就探個究竟吧!

MSDN上的解釋

http://forums.msdn.microsoft.com/zh-CN/clr/thread/bfa759a8-0cc0-4d65-8711-d2d0d6765687/

 

這時講得很詳細

http://www.artima.com/cppsource/pure_virtual.html

 

看看Codeproject上的一個例子

http://www.codeproject.com/KB/cpp/PureVirtualFunctionCall.aspx

 

(1)出現 Pure virtual function call 的原因是:

the child destructor is called and finished, so, we don’t have an object of type child now, but the current object (which is only being destructed) is of type Parent, so all calls in the destructor are calls to functions in this object. So, you can get a pure virtual function.

繼承類的對象析構被調用,而且完成了釋放,那麼現在這個對象就不存在了,但是當前的對象(正在釋構的父類對象)卻要調用其子類的虛函數實現(因為自身是純虛函數),所以就會出現Pure virtual function call error!

 

(2) 由物件導向的概念知,對象的析構是子類先析構再到父類析構,所以如果在父類中要調用自身的虛純數將會很危險了,而且在是運行時出現的。

 

以下是codeproject的例子

 

Class Parent{public: Parent() { } ~Parent() {  ClearALL();  }  void ClearALL() {  ThePure();   //調用自身的純虛函數,封裝一下是因為直接調用編譯器會識別出這樣調用是有問題的!}  virtual bool ThePure() = 0 ;}; class Child : public Parent{public: Child() { }  ~Child() { }  //The implementation of the pure virtual function  virtual bool ThePure()  {  return true; } };   void main(){ Child c;}

當C析構時,虛函數表裡的 ThePure()  已經登出,那麼父類 Parent 裡的ClearALL() 裡的ThePure() 虛表指標就會指向一個空地址(成了 dangling pointer 了), 所以在Parent裡調用 ClearALL() 就會出錯了

 

(3)如果上面的情況還算直觀的話,看看下面的一種造成 pure virtual function call的情況就更隱蔽了。

//不過我在VC6裡沒有問題class Base {public:    virtual void function() = 0;};class B : public Base{public:    virtual void function()     {        cout<<"pure function call in B"<<endl;    }};class A {public:    A(B* b):_b(b) {}    ~A()     {        _b->function();    }    B* _b;};B b;a(&b);int main(){    return 0;}

 

 

這種情況在某些編譯器下會出pure virtual function call錯誤。主要的原因是因為全域變數的釋放順序不確定,全域變數A依賴全域變數B。如果編譯器決定讓B先釋放,A後釋放。那麼,當A析構時,_b是一個dangling pointer。此時如果b對象的記憶體系統沒有釋放的話,那麼b的vptr表指向的是Base的vptr,而不是B的。此時,_b->function()就指向了pure virtual function了。詳細情況可以到看看

http://www.cnblogs.com/whjiang/archive/2007/10/22/932880.html

(5)論壇上關於出現pure virtual function call 的情況總結:

 

1. 基類構造器直接調用虛函數

2. 基類析構器直接調用虛函數

3. 基類構造器間接調用虛函數

4. 基類析構器間接調用虛函數

5. Calling a virtual function via a dangling pointer.

(4)為了在遇到 pure virtual function call 時不致於程式蹦掉,可以實現在一基類的純虛函數,但要記住找出原因後要刪掉實現的代碼

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.