覆蓋和隱藏

2021-04-18 04:03:50 字數 1802 閱讀 8324

c++中派生類函式遮擋(hide)基類中同名函式的問題是比較令人費解的,有必要詳細說明一下。

看看下面一段**:

class base;};

class derived : public base;};

derived *pd = new derived;

pd->f(10);

//編譯錯誤

對於這樣一種情況,scott meyers這樣解釋(effective c++中文第二版 第50條),derived::f遮蔽了base::f,即使兩者的引數型別並不相同。也就是說編譯器不知道有乙個引數型別為int的base::f存在。

但是下面的**卻可以編譯通過:

base *pb = new derived;

pb->f(10);

bjarne stroustrup在arm中對此的解釋是:假設當你呼叫f時,你真正想呼叫的時derived版本,但你意外地使用了錯誤的引數型別(本例為int)。更進一步假設derived是繼承體系中的一員,而且你並不知道derived間接繼承了某個baseclass,後者宣告有乙個虛函式f,需要乙個int引數。這種情況下你將意外呼叫baseclass::f——乙個你甚至並不知道它存在的函式。這種錯誤有可能在大型繼承體系中常常發生,所以stroustrup決定釜底抽薪(好乙個釜底抽薪!)地令derived class members遮蔽同名的base class members。

再看看以下**:

class base

;virtual void f(char* x) {};

};class derived : public base;};

derived *pd = new derived;

pd->f((char*)2);    // 編譯錯誤

pd->f(2);        // 通過

base *pb = new derived;

pb->f((char*)2);  // 通過

pb->f(2);        // 通過

根據以上的解釋,應該不難理解這樣的編譯結果。那麼我們看看靜態函式是否一樣的情況。

class base;};

class derived : public base

; //不論此定義前是否有 static,都有以下結果

};derived *pd = new derived;

pd->f(2); // 編譯錯誤

pd->f((void*)2);  

// 通過

base *pb = new derived;

pb->f(2);  //  通過

pb->f((void*)2);  // 錯誤

這樣我們發現對於static函式,一樣存在如上所述的遮蔽作用。c++允許派生類重新定義基類中的任何函式(private除外),這種權力是一把雙刃劍,在給予程式設計師能力的同時也誘導他們犯錯誤。

class base;};

class derived : public base;};

class son : public derived;};

son *ps = new son;

derived *pd = ps;

base *pb = pd;

ps->f(2); 

// 呼叫 son::f

pd->f(2); 

// 呼叫 son::f

pb->f(2); 

// 呼叫 base::f

以上這種在開發繼承層次很多的大型軟體時表現出來的精神**症就很難找到問題根源。

過載 覆蓋和隱藏

部分文字內容摘自 高質量c c程式設計 1 過載 overload 1 相同的範圍,在同乙個類中。2 函式名相同,引數不同。3 virtual可有可無。這在平時設計中用的比較多,比如遊戲中角色說話,可以設計成 void senddialog const char content 預設 void se...

隱藏和覆蓋 C

我可以給你說說我的理解 我認為隱藏和覆蓋的區別主要體現在 多型上 舉個例子 隱藏和覆蓋 include include using namespace std class a void f class b public a virtual void g int main 結果是 a a b invo...

C 覆蓋和隱藏

class people virtual void getname different params 隱藏規則2 1 函式名相同 引數相同 2 無virtual void getphone same params 覆蓋規則 1 函式名相同 引數相同 2 有virtual virtual void g...