C Primer第五版筆記 繼承中的類作用域

2021-08-25 11:13:24 字數 2050 閱讀 2066

每個類定義自己的作用域,在作用域中定義類的成員,當存在繼承關係時,派生類的作用域巢狀在其基類的作用域內。當乙個成員名字在派生類的作用域內無法解析的時候,編譯器將繼續在外層的基類作用域中尋找該名字的定義。

舉個例子:類b中有乙個函式名為f,類d繼承自類b,當通過d的物件呼叫函式f時會有如下流程:

1.首先在d中查詢,這一步沒有找到名字f;

2.因為d是b的派生類,所以接下來在b中查詢,此時找到名字f,所以使用的f函式最終被解析為b中的f。

因此,當呼叫p->mem()或obj.mem()時,將依次執行以下步驟:

1.首先確定p(或obj)的靜態型別。因為呼叫的是乙個成員,因此該型別必然是類型別;

2.在p(或obj)的靜態型別對應的類中查詢mem().如果找不到,則依次在直接基類中不斷查詢直到繼承鏈的頂端,如果仍然找不到,編譯器將報錯;

3.一旦找到mem,將進行常規型別檢查以確定這次的呼叫是否合法;

4.假如呼叫合法,則編譯器將根據呼叫的是不是虛函式而產生不同的**。

名字衝突與繼承:

派生類能重用定義在其直接基類或者間接基類中的名字:

struct base

protected:

int mem;

};struct der:base

int getm()

//通過作用域運算子使用隱藏的成員

int get_b_m()

protected:

int mem;

};int main(void)

名字檢查優於型別判斷:

即使在派生類成員與基類成員的引數列表不相同,基類成員依然會被隱藏:

class base 

};class sb:public base

};int main(void)

編譯器首先在sb中查詢名字f,因為在sb中確實有乙個名為f的成員,因此查詢過程就終止了,而sb中的f需要乙個引數,呼叫的語句無法提供實參,所以呼叫語句錯誤。

虛函式與作用域:

以上也是基類和派生類中的虛函式必須有相同引數列表的原因:

class base;

class d1:public base;

class d2:public d1;

覆蓋過載的函式:

和其它函式一樣,成員函式無論是不是虛函式都能被過載。派生類可以覆蓋過載函式的0個或多個例項。如果派生類希望所有的過載版本對它來說都是可見的,那麼他就需要覆蓋所有版本,或者乙個也不覆蓋。

有時乙個類僅需覆蓋過載集合中的一些而非全部函式,此時,如果不得不覆蓋基類的每乙個版本的話,操作將變得極為繁瑣。

一種好的解決方法就是使用using關鍵字,因為using宣告語句指定的是乙個名字而不指定引數列表,所以一條基類成員函式的using語句就能把該函式的所有過載例項新增到派生類的作用域中。此時,派生類只需要定義其特有的函式就可以了,而無需為繼承而來的其它函式重新定義。

class base 

int f(int i){}

int f(int i,int j){}

int f(double d){}

int f(double d,double e){}

void f(int a,double v){}

void f(int e,char a){}

double f(char s){}

char f(int r,char s,double a){}

char f(double g,char w){}

char f(double d,int f){}

};class sb:public base //在這裡只過載了乙個函式,

};class sb2:public base;

class sb3:public base //只過載部分

};int main(void)

C Primer第五版筆記 關聯容器

一 型別 關聯容器支援高效的關鍵字查詢和訪問,標準庫中兩個主要的關聯容器是map和set。map中的元素是鍵值對關鍵字表示索引。set中每個元素只包含乙個關鍵字,set支援高效的關鍵字查詢。關聯容器根據三個特性可以分為8種 1 set還是map 2 關鍵字是否可以重複,允許重複的容器名字中都包含單詞...

C Primer第五版筆記 動態陣列

allocator類 為了讓new分配乙個物件陣列,需要在型別名後跟方括號,括號中是分配物件的數目,該數目必須是整型,但不必是常量 new t 分配的記憶體並不是得到乙個陣列,而是得到乙個陣列元素型別的指標,因此不能對動態陣列呼叫begin和end 與普通陣列不同的是,普通陣列不能定義長度為0的陣列...

C Primer第五版筆記 拷貝控制

拷貝賦值函式 析構函式 三 五法則 default和阻止拷貝 乙個類通過定義五種特殊的成員函式來控制其拷貝 賦值 移動以及銷毀操作 拷貝建構函式 拷貝賦值運算子 移動建構函式 移動賦值運算子和析構函式。這些操作都是拷貝控制操作。當實現自己的類的時候要想好在做這些操作時的規則,因為編譯器通常會自動生成...