### 学习《C++ Primer》- 8
Part 8: 面向對象(第15章)
// @author: gr // @date: 2015-01-09 // @email: forgerui@gmail.com一、OOP
面向對象程序設計的核心思想是數據抽象、繼承和動態綁定。
數據抽象:可以將類的接口與實現分離
繼承:可以定義相似的類型并對其相似關系建模
動態綁定:在一定程度上忽略相似類型的區別,使用統一的方式使用它們的對象
二、定義基類或派生類
C++11中可以使用final關鍵字防止繼承的發生。
class Last final {private: int a;};在覆蓋基類的函數時,大意將參數列表寫錯,沒有構成覆蓋,將會是兩個獨立的函數。如果使用override關鍵字,編譯器會報marked override, but does not override的錯誤,提示有當前的問題。使用override需要保持基類和派生類的函數形式一致,并且基類的函數要聲明為virtual。
派生類可以轉換到基類,但不存在基類像派生類的轉換。從派生類向基類的轉換只對指針或引用類型有效。
三、虛函數
回避虛函數的機制
強迫執行虛函數的某個特定版本,使用作用域運算符可以實現這一目的:
多態性
使用虛函數,通過動態綁定實現,在運行時進行解析。
四、抽象基類
抽象類不能創建對象,只能作為接口,其它類繼承它。
含有純虛函數的類是抽象類。
五、訪問控制與繼承
派生類的成員或友元只能通過派生類對象來訪問基類的受保護成員。派生類對于一個基類對象中的受保護成員沒有任何訪問特權。
class Base{protected:int prot_mem;};class Sneaky : public Base{friend void clobber(Sneaky&);friend void clobber(Base&);int j;};//正確:clobber能訪問Sneaky對象的private和protected成員void clobber(Sneaky& s){s.j = s.prot_mem = 0;}//錯誤:clobber不能訪問Base的protected成員void clobber(Base& b){b.prot_mem = 0;}上面的第二個clobber函數因為不是Base的友元,所以無法訪問Base的protected成員。
派生訪問說明符的目的是控制派生類用戶(包括派生類的用戶、派生類的派生類)對于基類成員的訪問權限。
class Base{public:void pub_mem();protected:int prot_mem;privated:int priv_mem;};class Pub_Derv : public Base{int f() {return prot_mem;}char g() {return priv_mem;}};class Priv_Derv : private Base{int f1() const {return prot_mem;} };Pub_Derv d1;Priv_Derv d2;d1.pub_mem(); //正確:pub_mem在派生類中是public的d2.pub_mem(); //錯誤:pub_mem在派生類中是private的這樣,private派生訪問說明符表明繼承的成員是private,用戶無法訪問這個成員。使用public繼承便可以訪問。
class默認使用的是private繼承,struct默認使用的public繼承。
友元與繼承
友元關系不能繼承。基類的友元在訪問派生類成員時不具有特殊性,同樣,派生類的友元也不能隨意訪問基類的成員。
六、繼承中的類作用域
在編譯時進行名字查找
作用域從派生類到基類查找成員。
如果兩個成員名字相同,派生類的名字將隱藏基類的名字,但基類中的變量仍然存在。使用作用域運算符可以使用隱藏的名字。
名字查找優先于類型檢查
struct Base{int memfcn(); }; struct Derived : Base{int memfcn(int); } Base b; Derived d; b.memfcn(); //正確,調用Base::memfcn() d.memfcn(42); //正確,調用Derived::memfcn(int) d.memfcn(); //錯誤,調用Derived::memfcn(int),參數類型不一致 d.Base::memfcn(); //正確,調用Base:memfcn()從上面可以看出,查找到相同的名字就停止查找,所以基類的函數被隱藏了。之后再進行參數匹配,發現匹配不對,將會報錯。
覆蓋重載的函數
派生類可以覆蓋重載函數的0個或多個實例。如果派生類希望所有的重載版本對于它來說都是可見的,那么它就要覆蓋所有的版本,或者一個都不覆蓋。
有時,只需覆蓋一些而非全部函數時,不都不覆蓋每個基類中的每個版本。
解決方案是為重載的成員提供一條using聲明語句,使用using可以將子類的所有重載函數放入到當前作用域,這時在添加需要覆蓋的函數。
七、構造函數與拷貝控制
如果基類的函數是不可訪問或者刪除的,則派生類的函數也將是被刪除的。
八、容器與繼承
解決上面的問題,可以在容器中存放(智能)指針而非對象。
vector<shared_ptr<Quote>> basket;basket.push_back(make_shared<Quote>("1233", 50));basket.push_back(make_shared<Bulk_Quote>("12", 50, 10, .25));cout << basket.back()->net_price() << endl;轉載于:https://www.cnblogs.com/gr-nick/p/4238642.html
總結
以上是生活随笔為你收集整理的### 学习《C++ Primer》- 8的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 橙光游戏《ONE·一个》音乐歌曲BGM
- 下一篇: 幼儿园教案五十六个民族的来历介绍