程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> C++純虛函數調用

C++純虛函數調用

編輯:C++入門知識

    閱讀本文之前,讀者需要掌握 C++ 虛函數的基本用法,以及了解 C++ 的虛函數是怎麼實現的,此為基礎內容,不在本文的討論范圍。     在上次實習生面試中,面試官了我C++虛函數是怎樣實現的問題。我想讀過 Inside the C++ Object Model 這本書的人對這點都是比較熟悉的,在解釋過程中,他又問了我純虛函數是什麼,用來做什麼。我在回答的過程中簡單提了下“C++ 的純虛函數在特殊情況下是有可能會被調用的,具體的行為由 C++ 的標准庫的實現決定”,後來回想起這句話,想了好久沒想到具體的被調用的情況,幸好面試官沒追問這個問題,否則我真得語塞了(當時幾乎整個過程都是我在滔滔不絕的回答,面試官就一直嗯嗯嗯的狀態)。趁現在比較閒又不想復習考試,就順便寫寫代碼,針對這個問題總結出一篇博客文章與大家交流。     首先,必須清楚的是純虛函數本身是不應該被調用的!因為純虛函數是用來定義接口的,有時候基類自己找不到一個合情合理的實現,所以用虛函數的形式聲明,讓他的子類去做具體的實現。因此,如果純虛函數被調用了,那一定是你的程序裡出現了邏輯上的錯誤,這是我們在工作中需要了解和避免的,這也就是本文討論的目的之一啦。     你知道,虛函數是通過指針或者引用來調用的,調用的具體函數由指針/引用的實際決定。而這個實際的對象,是可以由這個對象的內存塊中的第一個值,vptr,指向虛函數表的指針來確定的。純虛函數是屬於基類的,所以要調用純虛函數,這個指針所指的對象必須是基類。但是呢,抽象類(包含了純虛函數的類)的對象是不允許被用戶定義的,唔,這個規定看似嚴謹,C++ 怎麼可能讓你去調用純虛函數,看本文的你也在好奇這個問題吧。不允許用戶定義抽象類的對象,是的,不代表這種對象不能被構造!記得對象的構造過程,是先調用基類的構造函數,再調用子類的構造函數,也就是先構造基類對象,再構造子類對象,對象的析構我就不提了哈。也就是說,在基類的構造函數裡調用的任何虛函數,都是調用基類自己的虛函數,而不是子類的虛函數,噢!漏洞就在這裡!

 Base{
:
      foo()=;
    Base()   { foo();  }    };
 Derived: Base{
     foo() {  }
};
 main() {
    Derived d;
}    很幸運的,編譯器能發現錯誤並向你吐槽,以下是我使用CodeBlocks(自帶MinGw的,含基於gcc 4.7.1的編譯器)編譯得到的一個警告和一個鏈接錯誤:編譯警告:warning: pure virtual 'virtual void Base::foo()' called from constructor 鏈接錯誤:undefined reference to `Base::foo()'     但是很不幸的,實際的應用中代碼往往復雜得多,使得編譯器無法在編譯的時候發現問題。修改上面的代碼如下,就可以成功的調用到虛函數了:  Base{
:
      foo()=;

    

};
 
 Derived: Base{
     foo() {  }
};
 
 main() {
    Derived d;
} 運行後得到的結果為:

 


Pony279原創博文,轉載請注明出處 http://www.cnblogs.com/Pony279/archive/2013/06/04/3117955.html

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved