C 學習 繼承中的作用域 10

2021-08-26 17:23:34 字數 2735 閱讀 2592

在繼承過程中,從基類派生出派生類,可能出現重名的成員,包括資料成員或成員函式,這些屬於作用域方面的內容。

一、基類的引用或指標訪問派生類

基類的引用或指標只能訪問派生類中屬於基類的部分成員,不能訪問派生類的部分,否則就會編譯出錯。

#include using namespace std; class cbase }; class cderived : public cbase }; int main()

執行結果:

呼叫基類的成員函式

呼叫基類的成員函式

呼叫派生類的成員函式

二、重複的資料成員

有時基類和派生類有同名的資料成員,甚至可能在基類和間接基類中都有同名的資料成員。

這種情況一般會出現在:從 由另乙個程式設計師建立的基類中派生自己的類,可能不知道在基類中有什麼私有資料成員,此時自己又建立了與基類當中同名的資料成員。

當然這種情況是不會阻礙繼承的,編譯器做了很多的工作。但這裡主要是介紹如何從派生類中呼叫派生類的同名私有成員或者基類的私有成員。

例子:cbase是cderived的父類,它們擁有乙個同名成員為mval。

在派生類中

1.預設是訪問自己的資料成員mval;

2.若要訪問基類的mval,要用這種格式"《類名》::《資料成員》", cbase::mval

#include using namespace std; class cbase int mval; }; class cderived : public cbase void printvalue() const int mval; }; int main()

執行結果:

犀利爹的年齡:120

犀利哥的年齡:100

三、重複的成員函式

基類與派生類若存在重複的成員函式,則有2種情況:

第一種情況:函式名相同,引數列表不同,如果將基類的成員函式的作用域引入派生類中,就是過載版本了

第二種情況:函式的所有方面都相同,包括函式名,引數列表與返回值

第一種情況:

函式名相同,引數列表不同,這跟函式的過載一樣。但這並不是函式的過載,因為函式的過載必須在同乙個作用域中定義,而基類和派生類定義了不同的作用域。在這裡,可以使用using在派生類中宣告基類的函式,將基類的函式的作用域引入派生類中的作用域,讓這裡的函式成為過載版本,來個小例子。

#include using namespace std; class cbase }; class cderived : public cbase }; int main()

執行結果:

呼叫派生類的列印函式: val = 2

呼叫基類的列印函式: str = hello

這裡如果沒有"using cbase::print;"的宣告,那麼將會編譯錯誤。

第二種情況:

函式的所有方面都相同,包括函式名,引數列表與返回值,在派生類中,要呼叫基類的同名成員函式,方法跟同名資料成員的方法一樣,格式是:"《類名》::《成員函式》"。

#include using namespace std; class cbase }; class cderived : public cbase }; int main()

執行結果:

呼叫派生類的成員函式

呼叫基類的成員函式

四、虛函式的作用域

關於虛函式的內容,就會涉及到動態繫結的知識了,這裡先不介紹,主要還是說明類繼承的作用域的問題。在類的繼承過程中,基類中的成員函式是不是虛函式,將會起著非常大的作用,先來看2個虛函式的例子。

1.在基類中沒有使用virtual關鍵字

#include using namespace std; class cbase }; class cderived1 : public cbase }; class cderived2 : public cderived1 }; int main()

執行結果:

呼叫cbase::print()

呼叫cbase::print()

呼叫cbase::print()

2.在基類中使用virtual關鍵字

#include using namespace std; class cbase }; class cderived1 : public cbase }; class cderived2 : public cderived1 }; int main()

執行結果:

呼叫cbase::print()

呼叫cderived1::print()

呼叫cderived2::print()

1,2兩個例子可以看到,乙個virtual的關鍵字起著這麼大的作用。當基類的成員函式使用virtual關鍵字修飾的話,基類指標會根據指向的物件的實際型別來尋找相應的類的成員函式的定義。要獲得動態繫結,必須通過基類的引用或指標呼叫虛成員。

在第二個例子中,將print函式宣告為虛函式,這樣子編譯器會生成**,在執行時基於引用或指標所繫結的物件的實際型別進行呼叫。bp2指向cderived1物件,bp3指向cderived2物件,所以都是呼叫屬於自己的print函式版本。

繼承中類的作用域

派生類的作用域巢狀在其基類的作用域之內,如果乙個名字無法在派生類的作用域內無法正確解析,則編譯器將繼續在外層的基類作用域中尋找該名字的定義。派生類中能重定義在其直接基類或間接基類中的名字,此時定義在內層作用域 即派生類 的名字將隱藏定義在外層作用域 即基類 的名字。struct base prote...

繼承中的類作用域 1

每個類定義自己的作用域,當存在繼承關係時,派生類的作用域巢狀在其基類的作用域中。1 乙個物件 引用或指標的靜態型別決定了該物件的哪些成員是可見的,即使靜態型別與動態型別不一致 當使用基類的引用或指標時,會發生這種情況 2 派生類的成員將隱藏同名的基類成員,使用作用域來使用乙個被隱藏的基類成員 3 名...

C 中變數的作用域

作用域 scope 是程式的一部分,在其中名字有其特定含義 c 語言中大多數作用域都以花括號分隔 注意 同乙個名字在不同的作用域中可能是指向的是不同的實體,實體的有效區域始於名字的宣告語句,以宣告語句所在的作用域末端結束 int main 如上面的程式的例子,main定義於所有花括號之外,所以是擁有...