可以直接調用的純虛函數


昨天提到了子在構造函數和析構函數中調用虛函數的問題。白天的時候翻了一下《深入理解C++對象模型》,結果還真發現一點兒有趣的東西。

文中如是說:很多C++新手會驚奇的發現純虛函數竟然可以定義(在聲明的基類中定義),並且可以被調用(靜態調用)!看來我還是新手啊,廢話少說,上代碼!

#include <iostream>
using namespace std;

class Base{
  public:
    Base(){}
    void callVirFunc();
    virtual ~Base(){};

  private:
    virtual void virFunc() = 0;//注意是私有的哦!
};

class Derived:public Base{
  public:
    Derived(){}

  private:
    virtual void virFunc();//這里也是私有的哦!
};

void Base::virFunc(){
  cout<<"Virtual function static defined in Base!"<<endl;
}

void Base::callVirFunc(){
  virFunc();//調用Derived class中的實現版本
  Base::virFunc();//調用Base class中的static版本
}

void Derived::virFunc(){
  cout<<"Virtual function defined in Derived!"<<endl;
}

int main(){
  Base *pd = new Derived;
  pd->callVirFunc();
  delete pd;

  return 0;
}

 

運行結果:

:!./pure_virtual_func_test
Virtual function defined in Derived!
Virtual function static defined in Base!

 

例子中, Base class中的callVirFunc函數分別調用了在Base class中定義的純虛函數版本和Derived class中的實現版本。神奇吧!

 

其實這個例子是很特殊的哦!它還是反映了另外一個有趣的問題哦!注意!Base class中的callVirFunc函數調用了Derived class中的私有虛函數!它竟然繞過了訪問控制機制!對於這個問題,CSDN中的兄弟們進行了激烈的討論(在這里http://topic.csdn.net/t/20040805/16/3245820.html)。我想說的是,從編譯器的角度看,這是完全沒有問題的,因為當前對象的類類型是Derived,它的vptr指向Derived的虛函數表。還有一個問題就是,在虛函數表中並沒有訪問控制信息,所以此時調用虛函數的時候,拿到的當然就是Derived的版本並正確執行嘍。這種做法確實可以造成一些看起來詭異的程序行為,所以盡量避免這樣做吧。如果想讓程序更有序,更清晰,在虛函數中調用私有的本地函數是比較好的方式。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM