C++ Primer 5th笔记(chap 15 OOP)继承中的类作用域
1. 派生類的作用域
每個(gè)類定義自己的作用域,作用域內(nèi)定義成員,當(dāng)存在繼承關(guān)系時(shí),派生類的作用域嵌套在其基類的作用域之內(nèi)。如果一個(gè)名字在派生類的作用域內(nèi)無法正確解析,則編譯器將繼續(xù)在外層的基類作用域中尋找該名字的定義。
Bulk_quote bulk; cout << bulk.isbn();. 首先在Bulk_quote 中查找名字isbn.
. 在Bulk_quote的基類Disc_quote中查找.
. 在Disc_quote的基類Quote中查找.
1.1 在編譯時(shí)進(jìn)行名字查找
一個(gè)對(duì)象、引用或指針的靜態(tài)類型決定了該對(duì)象的哪些成員可見,即使動(dòng)態(tài)類型和靜態(tài)類型不一致。
namespace oopClassDomainTest {class Quote {};class Disc_quote : public Quote {public:Disc_quote() {};void discount_policy() { } };class Bulk_quote : public Disc_quote {};void test() {Bulk_quote bulk;Bulk_quote* bulkP = &bulk;//靜態(tài)類型和動(dòng)態(tài)類型一致Quote* itemP = &bulk;//靜態(tài)類型和動(dòng)態(tài)類型不一致bulkP->discount_policy(); //okitemP->discount_policy();//error} }1.2. 名字沖突與繼承
派生類可以重定義基類成員,從而將其隱藏。但可以通過作用域運(yùn)算符來使用隱藏的成員
struct Base {Base() : mem(0) { }protected:int mem;};struct Derived : Base {Derived(int i) : mem(i) { } // initializes Derived::mem to i// Base::mem is default initializedint get_mem() { return mem; } // returns Derived::memint get_base_mem() { return Base::mem; }// . . .protected:int mem; // hides mem in the base};void test() {Derived d(42);cout << d.get_mem() << endl; // prints 42cout << d.get_base_mem() << endl; // prints 0}1.3 名字查找優(yōu)先于類型檢查
聲明在內(nèi)層作用域的函數(shù)并不會(huì)重載聲明在外層作用域的函數(shù),如果派生類中的函數(shù)與基類的某個(gè)成員同名,則派生類將在其作用域內(nèi)隱藏該基類成員,即使形參列表不一致。
namespace oopClassDomainTest3 {struct Base { int memfcn() { return 1; };};struct Derived : Base {int memfcn(int) { return 1; };// hides mem in the base };void test() {Derived d;Base b;b.memfcn();d.memfcn(10);//d.memfcn();//errord.Base::memfcn();//ok } }1.4 虛函數(shù)和作用域
不論靜態(tài)類型,調(diào)用的是虛函數(shù)結(jié)果就是虛函數(shù)。
class Base {public:virtual int fcn();};class D1 : public Base {public:// hides fcn in the base; this fcn is not virtual// D1 inherits the definition of Base::fcn() int fcn(int); // parameter list differs from fcn in Basevirtual void f2(); // new virtual function that does not exist in Base};class D2 final : public D1 {public:int fcn(int); // nonvirtual function hides D1::fcn(int)int fcn(); // overrides virtual fcn from Basevoid f2(); // overrides virtual f2 from D1};D1 dobj, * dp = &dobj;dp->fcn(42); // ok: static call to D1::fcn(int)Base bobj; D1 d1obj; D2 d2obj;Base* bp1 = &bobj, * bp2 = &d1obj, * bp3 = &d2obj;bp1->fcn(); // 虛調(diào)用, Base::fcn bp2->fcn(); // 虛調(diào)用, Base::fcn at run timebp3->fcn(); // 虛調(diào)用, D2::fcn at run timeD1* d1p = &d1obj; D2* d2p = &d2obj;d1p->f2(); // 虛調(diào)用, will call D1::f2() at run timed2p->f2(); // 虛調(diào)用, will call D2::f2() at run timeD1* p2 = &d2obj; D2* p3 = &d2obj;p2->fcn(42); // statically bound, calls D1::fcn(int)p3->fcn(42); // statically bound, calls D2::fcn(int)D1* dp1 = &d2obj; D2* dp2 = &d2obj;dp1->fcn(10); // static call to D1::fcn(int)dp2->fcn(10); // static call to D2::fcn(int)1.5 覆蓋重載函數(shù)
應(yīng)用場(chǎng)景:基類中可能有多個(gè)重載函數(shù),派生類希望覆蓋重載函數(shù)中的一部分。
解決方法:使用using聲明語(yǔ)句指定一個(gè)名字而不指定形參列表,一條基類成員函數(shù)的using聲明語(yǔ)句就可以把該函數(shù)所有重載實(shí)例添加到派生類作用域。 之后派生類僅需對(duì)特定參數(shù)的函數(shù)定義,無需為其他繼承而來的函數(shù)定義。
聲明在內(nèi)層作用域的函數(shù)并不會(huì)重載外層作用域的函數(shù),因此定義派生類的函數(shù)也不會(huì)重載其基類中的成員。如果同名則外層的名字隱藏。
【引用】
[1] 代碼oopTest.h
總結(jié)
以上是生活随笔為你收集整理的C++ Primer 5th笔记(chap 15 OOP)继承中的类作用域的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Hyperledger Fabric V
- 下一篇: C++ Primer 5th笔记(cha