23、C++ Primer 4th 筆記,物件導向編程(1)

來源:互聯網
上載者:User

1、繼承,動態綁定,資料抽象一起成為物件導向編程的基礎。

2、模板使我們能夠編寫獨立於具體類型的泛型類和泛型函數。在C++中,用類進行資料抽象,用類派生從一個類繼承另一個類:衍生類別繼承基類的成員。動態綁定使編譯器能夠在運行時決定是使用基類中定義的函數還是類中定義的函數。

3、C++中,多態性僅用於通過繼承而相關聯的類型的引用或指標。

4、定義為virtual的函數是基類期待衍生類別重新定義的。保留字virtual只在類內部的成員函式宣告中出現。

5、一旦函數在基類中聲明為虛函數,它就一直為虛函數。

6、衍生類別對象由多個部分組成:衍生類別本身定義的(非static)成員加上由基類(非static)成員組成的子物件。

7、已定義的類才可以作為基類。

8、如果需要聲明(但並不實現)一個衍生類別,則先聲明包含類名但不包含衍生的資料行表。

樣本

//error: a forward declaration must not include the derivation listclass Bulk_item : public Item_base;//正確的前向聲明為:// forward declarations of both derived and nonderived classclass Bulk_item;class Item_base;

9、要觸發動態綁定,要滿足兩個條件:(1)只有指定為虛成員函數才能動態綁定;(2)必須通過基類類型的引用或指標進行函數調用。

基類類型的引用或指標可以引用基類類型對象,也可以引用衍生類別型對象。

10、基類類型引用和指標的關鍵點在於靜態類型(在編譯時間可知的參考型別或指標類型)和動態類型(指標或引用所綁定的對象的類型這是僅在運行時可知的)可能不同。

引用和指標的靜態類型與動態類型可以不同,這是C++可以支援多態性的基石。

11、覆蓋虛函數機制

    有時,希望覆蓋虛函數機制並強制函數調用使用虛函數的特定版本,可以使用範圍操作符:

樣本

Item_base *baseP = &derived;double d = baseP->Item_base::net_price(42); //調用基類的版本

12、衍生類別虛函數調用基類版本時,必須顯式使用範圍操作符。如果衍生類別函數忽略了這樣做,則函數調用會在運行時確定並且將是一個自身調用,從而導致無窮遞迴。(指的是在衍生類別虛函數中調用基類的同名的函數,從而讓基類做一些必要的工作)

13、像其他任何函數一樣,虛函數也可以有預設實參。通常,如果有用在給定調用中的預設實參值,該值將在編譯時間確定。如果一個調用省略了具有預設值的實參,則所用的值由調用該函數的類型定義,與對象的動態類型無關。通過基類的引用或指標調用虛函數時,預設實參為在基類虛函式宣告中指定的值,如果通過衍生類別的指標或引用調用虛函數,則預設實參是在衍生類別的版本中聲明的值。

在同一虛函數的基類版本和衍生類別版本中使用不同的預設實參幾乎一定會引起麻煩。如果通過基類的引用或指標調用虛函數,但實際執行的是衍生類別中定義的版本,這時就可能會出現問題。在這種情況下,為虛函數的基類版本定義的預設實參將傳給衍生類別定義的版本,而衍生類別版本是用不同的預設實參定義的。

14、如果成員在基類中為private,則只有基類和基類的友元可以訪問該成員。

15、介面繼承和實現繼承

public衍生類別繼承基類的的介面,它具有與基類相同的介面,稱為介面繼承。

private和protected派生的類不繼承基類的介面,稱為實現繼承。衍生類別的實現中使用被繼承類但繼承基類的部分並未成為其介面的一部分。

16、繼承:反映的是is a的關係。組合反映的是has a的關係。

17、可以通過using聲明訪問基類中的名字(使用private繼承才有這個必要)。

樣本

class Derived:private base{public:using Base::SIZE;//...};

18、使用class保留字定義的衍生類別預設具有private繼承,而用struct保留字定義的類預設具有public繼承。這是他們唯一的區別:預設的成員保護層級和預設的派生保護層級。

19、友元關係和繼承

友元關係不能繼承。基類的友元對從該基類派生的類沒有特殊存取權限。

在http://www.cnblogs.com/mydomain/archive/2011/03/22/1991244.html中,我經過VS2008編譯環境測試得出友元關係可以繼承。而C++ Primer 4th中第15章講到這個情況時說不能繼承。對其例子進行了測試,發現也是可以通過編譯的。

應當是編譯環境的問題。

樣本

#include "iostream"#include "vector"#include "algorithm"#include "string"#include "functional"using namespace std;class Base{friend class Frnd;protected:int i;};class D1:public Base{protected:int j;};class Frnd{public:int mem(Base d) {return d.i;}int mem(D1 d1) {return d1.i;} //error:friendship dosenot inherit};class D2:public Frnd{public:int mem(Base d) {return d.i;};//“Base::i”: 無法訪問 protected 成員,在編譯中出錯};int main(){return 0;}

20、繼承和靜態成員

    如果基類定義 static 成員,則整個繼承層次中只有一個這樣的成員。無論從基類派生出多少個衍生類別,每個 static 成員只有一個執行個體。static 成員遵循常規存取控制:如果成員在基類中為 private,則衍生類別不能訪問它。假定可以訪問成員,則既可以通過基類訪問 static 成員,也可以通過衍生類別訪問 static 成員。一般而言,既可以使用範圍操作符也可以使用點或箭頭成員訪問操作符。

參考

[1] http://blog.163.com/zhoumhan_0351/blog/static/3995422720100284731826/

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.