繼承中類的作用域

2022-05-28 04:27:08 字數 1857 閱讀 3722

派生類的作用域巢狀在其基類的作用域之內,如果乙個名字無法在派生類的作用域內無法正確解析,則編譯器將繼續在外層的基類作用域中尋找該名字的定義。

派生類中能重定義在其直接基類或間接基類中的名字,此時定義在內層作用域(即派生類)的名字將隱藏定義在外層作用域(即基類)的名字。

struct base

protected int mem;

};struct derived : base

int get_mem()

protected int mem; //@ 隱藏基類中的mem

};

可以通過作用域符來訪問被隱藏的基類成員:

struct derived : base

//...

};

作用運算子將覆蓋掉原有的查詢規則,並指示編譯器從base類的作用域開始查詢mem

注意:除了覆蓋繼承而來的虛函式之外,派生類最好不要重用其他定義在基類中的名字。

如果派生類的成員與基類的某個成員同名,則派生類將在其作用域內隱藏該基類成員,即使派生類成員與基類成員的形參列表不一致,基類成員也會被隱藏。

struct base;

struct derived : base;

derived d;base b;

b.memfunc(); //@ 正確

d.memfunc(10); //@ 正確

d.memfunc(); //@ 錯誤,引數列表為空的基類成員函式被隱藏

d.base::memfunc(); //@ 正確

基類和派生類的虛函式接受的實參必須相同,否則就無法通過基類的引用或者指標呼叫派生類的虛函式。

class base;

class d1 : public base;

class d2 : public d1;

base bobj;d1 d1obj;d2 d2obj;

base* bp1 = &bobj,*bp2 = &d1obj,*bp3 = &d2obj;

bp1->fun(); //@ 呼叫base::fun

bp2->fun(); //@ 呼叫base::fun

bp3->fun(); //@ 呼叫d2::fun

d1 *d1p = &d1obj;d2 *d2p = &d2obj;

bp2->f2(); //@ 錯誤,base沒有名字為f2的成員

d1p->f2(); //@ 呼叫d1::f2

d2p->f2(); //@ 呼叫d2::f2

base *p1 = &d2obj;d1 *p2 = &d2onj;d2 *p3 = &2dobj;

p1->fun(42); //@ 錯誤,base中沒有接受乙個int的fun

p2->fun(42); //@ 靜態繫結,呼叫d1::fun(int)

p3->fun(42); //@ 靜態繫結,呼叫d2::fun(int)

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

有時候只需要覆蓋過載集合中的乙個版本,而不得不覆蓋基類中的每乙個版本,顯然很麻煩。一種的好的解決辦法是為過載成員提供一條using宣告語句,這樣就不需要覆蓋基類中的每乙個過載版本。using 宣告語句指定了乙個名字而不指定形參列表,所以一條基類成員函式的using宣告語句就能把該函式的所有過載例項新增到派生類的作用域中,此時派生類只需要定義其特有的版本即可,無需為繼承而來的。

繼承中的類作用域 1

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

C 中的類作用域

在類中定義的名稱 如類資料成員名和類成員函式名 的作用域都為整個類,作用域為整個類的名稱只在該類中是已知的,在類外是不可知的。因此,可以在不同類中使用相同的類成員名而不會引起衝突。作用域為類的常量 class bakery 通過上述描述建立乙個由所有物件共享的常量的方式有誤!因為類宣告只是描述了物件...

類的作用域

更多c 類的基本概念 每個類都會定義它自己的作用域。在類的作用域外,普通的資料和函式成員只能由物件 引用或者指標使用成員訪問運算子來訪問。對於類型別成員則使用作用域運算子訪問。不論哪種情況,跟在運算子之後的名字都必須是對應類的成員。作用域和定義在類外部的成員 乙個類就是乙個作用域很好地解釋為什麼當我...