protectedInheritance.cpp
間接繼承和書本描述不一致,書上說因為第一重繼承變private,第二重繼承才無法訪問Base::i~是private,現實是提示Base::i是protected,好像跳過Private_derived類直接找基類了。
繼承對基類的保護,還是普遍規律,只能越來越嚴,不能變松。
還有,標號不是限制衍生類別對基類成員(表達不清楚,是基類成員還是從基類繼承過來的成員?)的訪問,
原話:所有繼承Base的類對Base中的成員具有相同的訪問(指什麼,成員?怎麼理解恰當,衍生類別包括基類,所以這裡的對基類訪問指對衍生類別中包含的基類部分訪問?)
標號是限制使用者和衍生類別的衍生類別(也當作一種使用者吧?)對衍生類別(從基類繼承來的)成員的訪問
//公用、私人和受保護的繼承#include<iostream>class Base{public:void basemem();protected:int i;};//struct直接繼承class?可以?還有預設存取層級不同,一個public,一個private,轉換後不要忘了struct Public_derived : public Base{int use_base() { return i; }//顧名思義,使用一下base看看};struct Protected_derived : protected Base{int use_base() { return i; }};struct Private_derived : private Base{int use_base() { return i; }//也沒問題,儘管private~~~private不是設給它的,是給使用者和下一個衍生類別的};//下一層派生struct Derived_from_Private : public Private_derived{int use_base() { return i; }//書上的注釋,Base::i is private in Private_derived,//實際錯誤提示:'int Base::i' is protected,可能說明直接以使用者身份去Base裡找了,是protected,如果間接找,這個提示費勁};struct Derived_from_Public : public Public_derived{int use_base() { return i; }//可以訪問,因為Base::i在Public_derived類中仍然是protected};int main(){Base b;Public_derived d1;Protected_derived d3;Private_derived d2;b.basemem();//b對象,肯定能訪問d1.basemem();//對於d1對象,basemem()還是public//d2.basemem();//basemem()是private,不能訪問//d3.basemem();//protected當然也不行了}
介面繼承與實現繼承:
public派生的類與基類有相同的介面。在設計良好的層次中,public派生的類可以用在任何需要基類對象的地方。
非public派生的類不繼承基類的介面,稱為實現繼承,(用基類做它的實現,但不用基類做介面)
using.cpp
經過測試,using的用法和書上差距很大~!!!!!!!!!!!!!!!!!!(mark)
base的protected,用private繼承,結果過用using可以變成public~~~!!!!
另:基類和衍生類別指標相容與轉換問題也測了一下,結果比較符合我“想當然”的判斷。。
到底衍生類別的constructor怎麼定義,把基類的成員用using聲明了一遍,但是constructor的初始化列表會提示找不到成員n
//衍生類別使用using聲明恢複繼承成員的存取層級。#include<iostream>class Base{public:std::size_t size() const { return n; }protected:std::size_t n;};class Derived : private Base{//private繼承,全部成員變成私人public:using Base::size;//using Base::n;//神奇了,可以提升為public,直接d1.n就訪問了。神奇的不是Geany編譯器和g++吧protected://using Base::n;private://聲明成private也行啊。。。到底何謂“不能使存取層級比基類中原來指定的更嚴格或更寬鬆”using Base::n;//無論聲明放在protected還是private後邊,d1.n都提示n是protected。但public...//~小失誤,把基類的n設為private,這種情況到底有何不同~恢複為private也有錯啊?};class Public_derived : public Base{//private繼承,全部成員變成私人public://using Base::size;protected://using Base::n;private://using Base::n;};int main(){/*Base b1;Derived d1;Public_derived pd1;//猜測:一個對象的儲存地區是順序存放各類對象的,首地址是基類子物件,其次是衍生類別多出來的部分,再次是衍生類別的衍生類別。。。Base *bp1 = &d1;//private繼承已經改變了基類的存取權限,所以基類指標也不能指向它了~“Base是Derived裡不能訪問的一部分”,因此public繼承是一個前提。bp1 = &pd1;Public_derived *pdp1 = bp1;//前提:public。衍生類別的指標是不能指向基類的對象的,只能向下相容Derived *dp1 = &b1;//不能向上相容,所以和地址猜想不衝突,這說明很可能就是哪樣排列的,所以不能分。*/Derived d1;std::cout << d1.n;//這提升許可權到public,但是無法初始化,我始終都搞不定衍生類別的初始化。。。}
預設繼承保護層級(前邊疑問的class和struct有解了):
default inheritance.cpp
比較簡單的概念,預設不重要,自己可以手動設定
//預設繼承保護層級class Base{};struct D1 : Base{};//public inheritance by defaultclass D2 : Base{};//private inheritance by default//這隻是預設的,如果你每次都指定,還是無所謂。。。//原書:class和struct唯一的不同是預設的成員保護層級和預設的派生保護層級(這倆詞指什麼)//以下D3和D4的定義兩兩相同class D3 : public Base{public:/*...*/};//equivalent definition of D3struct D3 : Base {//inheritance public by default/*...*///initial number access public by default};struct D4 : Base {private:/*...*/};//equivalent definition of D4class D4 : Base {//inheritance private by default/*...*///initial member access private by default};//tips:因為私人繼承在使用class保留字是預設情況,但因為實踐中使用罕見,所以還要顯式的使用privateint main(){}
為何可以訪問,卻不可以利用建構函式初始化基類成員,衍生類別中的基類成員,莫非也用基類的建構函式來完成
class Gif : public Picture_format{public:Gif(size_t i = 20) : pixels(i) {}size_t fcn(){ return pixels; }};
pe15_11.cpp
弄明白的東西:
繼承來的成員的地位:
衍生類別的constructor無法在初始化列表中初始化繼承成員,識別不到
對衍生類別對象來說,繼承的成員也是基類的constructor初始化的,但是衍生類別能直接讀取它,fcn()中使用pixels
如此說來,基類衍生類別貌似真是分開的模組
class Picture_format{public:Picture_format(size_t i = 10) : pixels(i) {}protected:size_t pixels;//像素private:};class Gif : public Picture_format{public:size_t fcn(){ return pixels; }};//Gif g();//這個g不算類Gif的類對象,算個函數什麼的吧?!Gif g;std::cout << g.fcn() << std::endl;