程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> Effective C++:條款36:絕不重新定義繼承而來的non-virtual函數

Effective C++:條款36:絕不重新定義繼承而來的non-virtual函數

編輯:C++入門知識

(一)首先有下面的繼承體系:

class B { 
public: 
    void mf(); 
    ... 
}; 
class D : public B {...};

D x;

以下行為:

B* pB = &x;

pB->mf();

異於以下行為:

D* pD = &x;

pD->mf();

上面兩種行為產生的結果不一定相同。看下面這種情況:

mf是個non-virtual函數而D定義有自己的mf版本:

class D : public B { 
public: 
    void mf(); 
    ... 
}; 
pB->mf();//調用B::mf 
pD->mf();//調用D::mf

對於同一個對象d,使用不同類型的指針指向它時,他表現得不盡相同。同理對於引用也是一樣。


(二)上述現象的原因:

(1)造成這一行為的原因是,non-virtual函數都是靜態綁定的。由於pB被聲明為一個pointer-to-B,通過pB調用的non-virtual函數永遠是B所定義的版本,即使pB指向一個類型為“B派生之Class”的對象。
(2)virtual函數是動態綁定的,如果mf是個virtual函數,不論通過pB還是通過pD調用mf,都會導致調用D::mf,因為pB和pD真正指的都是D的對象。


(三)

條款7“為多態基類聲明虛析構函數”是本條款要求的特例:派生類可能有更多的成員變量和相應操作,因而析構函數必須與基類不同,采用虛析構函數的方法可以使用“動態綁定”從而產生安全的析構行為;反之,如果聲明為非虛析構函數,必須重新定義,這和本條款的要求相違背。


請記住:

(1)絕對不要重新定義繼承而來的 non-virtual 函數。



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