1. 程式人生 > >公有、私有和受保護的繼承--《C++ primer》筆記

公有、私有和受保護的繼承--《C++ primer》筆記

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 default
class D2 : Base{};		//private inheritance by default
//這只是預設的,如果你每次都指定,還是無所謂。。。
//原書:class和struct唯一的不同是預設的成員保護級別和預設的派生保護級別(這倆詞指什麼)


//以下D3和D4的定義兩兩相同
class D3 : public Base{
public:
	/*...*/
};
//equivalent definition of D3
struct D3 : Base {		//inheritance public by default
	/*...*/				//initial number access public by default
};

struct D4 : Base {
private:
	/*...*/
};
//equivalent definition of D4
class D4 : Base {	//inheritance private by default
	/*...*/				//initial member access private by default
};
//tips:因為私有繼承在使用class保留字是預設情況,但因為實踐中使用罕見,所以還要顯式的使用private
int 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;