欧美一级特黄大片做受成人-亚洲成人一区二区电影-激情熟女一区二区三区-日韩专区欧美专区国产专区

【C++】繼承-創(chuàng)新互聯(lián)

在新吳等地區(qū),都構(gòu)建了全面的區(qū)域性戰(zhàn)略布局,加強(qiáng)發(fā)展的系統(tǒng)性、市場(chǎng)前瞻性、產(chǎn)品創(chuàng)新能力,以專注、極致的服務(wù)理念,為客戶提供成都網(wǎng)站設(shè)計(jì)、網(wǎng)站制作 網(wǎng)站設(shè)計(jì)制作定制開(kāi)發(fā),公司網(wǎng)站建設(shè),企業(yè)網(wǎng)站建設(shè),品牌網(wǎng)站設(shè)計(jì),成都全網(wǎng)營(yíng)銷推廣,成都外貿(mào)網(wǎng)站建設(shè)公司,新吳網(wǎng)站建設(shè)費(fèi)用合理。

目錄

一、繼承的概念

二、被繼承成員訪問(wèn)方式的變化

三、賦值兼容規(guī)則(切片)?

四、繼承中的作用域

五、子類的默認(rèn)成員函數(shù)

1、父、子類中各自的成員處理方式

2、需要自己寫默認(rèn)成員函數(shù)的情況

3、子類中默認(rèn)成員函數(shù)的寫法

3.1父類沒(méi)有默認(rèn)構(gòu)造函數(shù),需要在子類的構(gòu)造函數(shù)里補(bǔ)充

3.2在子類中顯式寫拷貝構(gòu)造

3.3在子類中顯式寫賦值運(yùn)算符重載

3.4不需要顯式調(diào)用析構(gòu)函數(shù)

六、繼承和友元、靜態(tài)成員的關(guān)系

七、菱形繼承和菱形的虛擬繼承

1、菱形繼承

2、二義性和數(shù)據(jù)冗余

3、虛擬繼承解決二義性和數(shù)據(jù)冗余

4、virtual關(guān)鍵字解決二義性和數(shù)據(jù)冗余的方法

4.1未使用virtual關(guān)鍵字

4.2使用virtual關(guān)鍵字

4.3虛繼承+重寫問(wèn)題

八、繼承和組合的區(qū)別

1、組合的使用場(chǎng)景

2、繼承和組合的區(qū)別


一、繼承的概念

繼承機(jī)制是面向?qū)ο蟪绦蛟O(shè)計(jì)使代碼可以復(fù)用的最重要的手段,它允許程序員在保持原有類特性的基礎(chǔ)上進(jìn)行擴(kuò)展,增加功能,這樣產(chǎn)生新的類,稱子類(派生類)。以前我們接觸的復(fù)用都是函數(shù)復(fù)用,繼承是類設(shè)計(jì)層次的復(fù)用。

現(xiàn)在有學(xué)生類和老師類,類中均有年齡、性別等相同的屬性,這些相同的屬性在每個(gè)類中都寫一份就會(huì)出現(xiàn)代碼的冗余??梢允褂靡粋€(gè)父類包含這些共有的成員變量和成員函數(shù),讓學(xué)生類、老師類作為子類對(duì)父類進(jìn)行繼承即可。

二、被繼承成員訪問(wèn)方式的變化

public繼承

protected繼承

private繼承

父類的public成員

public

protected

private

父類的protected成員

protected

protected

private

父類的private成員

子類不可見(jiàn)

子類不可見(jiàn)

子類不可見(jiàn)

1、父類的private成員被子類繼承后是不可見(jiàn)的。不可見(jiàn)指的是父類的private成員會(huì)被繼承到子類,但是子類無(wú)論是在類里面還是類外面,都無(wú)法對(duì)這些被繼承的私有成員進(jìn)行訪問(wèn)。(但是可以使用繼承的“獲取成員變量的偷家函數(shù)”對(duì)這些不可見(jiàn)的成員變量進(jìn)行修改、訪問(wèn))

2、除了父類中的private成員,其他成員被子類繼承后最終的訪問(wèn)方式取決于該成員在父類中的權(quán)限和繼承權(quán)限兩者權(quán)限較小的那個(gè)。

3、可以看出protected限定符是因?yàn)槔^承才出現(xiàn)的。保護(hù)和私有在當(dāng)前類中沒(méi)有區(qū)別,但子類繼承時(shí),父類中的私有成員子類是不可見(jiàn)的,而保護(hù)成員是可見(jiàn)的。

4、在實(shí)際中一般使用都是public繼承,因?yàn)閜rotetced/private繼承下來(lái)的成員都只能在派生類的類里面使用,實(shí)際中擴(kuò)展維護(hù)性不強(qiáng)。父類一般是公有和保護(hù),不使用私有。

5、class默認(rèn)私有繼承,struct默認(rèn)公有繼承。但好習(xí)慣是寫明繼承方式。

struct Student : public person
{

};
struct Teacher :person//不提倡,最好寫明繼承方式
{
};
三、賦值兼容規(guī)則(切片)?
class Person
{
protected:
	string _name;
	string _sex;
	int _age;
};
class Student : public Person
{
public:
	int _num;//學(xué)號(hào)
};
int main()
{
	Person p;
	Student s;
	//父類=子類 賦值兼容/切割/切片
	p = s;//父類對(duì)象
	Person* ptr = &s;//父類的指針
	Person& ref = s;//父類的引用
	return 0;
}

1、子類對(duì)象可以賦值給父類對(duì)象、父類的指針、父類的引用。這種操作叫做賦值兼容/切割/切片,意為將子類對(duì)象中繼承于父類的成員切割下來(lái)賦值給父類對(duì)象。這不是類型轉(zhuǎn)換,是天然的賦值行為。(切片僅限公有繼承。舉例:父類為公有,子類保護(hù)或私有繼承后,成員變?yōu)楸Wo(hù)和私有,子類再切片給父類,那么被繼承的成員權(quán)限會(huì)變,所以切片僅限公有繼承)

2、只能將子類對(duì)象賦值給父類,父類對(duì)象不能給子類賦值。但是指針和引用卻可以,不過(guò)存在越界風(fēng)險(xiǎn)。

int main()
{
	Person p;
	Student s;
	//s = (Student)p;//父類對(duì)象無(wú)法賦值給子類,強(qiáng)轉(zhuǎn)也不行
	Student* ptr = (Student*)& p;//類型強(qiáng)轉(zhuǎn),有越界風(fēng)險(xiǎn)
	Student& ref = (Student&)p;//類型強(qiáng)轉(zhuǎn),有越界風(fēng)險(xiǎn)
	return 0;
}

3、基類的指針或者引用可以通過(guò)強(qiáng)制類型轉(zhuǎn)換賦值給派生類的指針或者引用。但是必須是基類的指針是指向派生類對(duì)象時(shí)才是安全的。這里基類如果是多態(tài)類型,可以使用RTTI(Run-Time Type Information)的dynamic_cast 來(lái)進(jìn)行識(shí)別后進(jìn)行安全轉(zhuǎn)換。

四、繼承中的作用域

1、在繼承中父類和子類都有自己獨(dú)立的類域。

2、當(dāng)子類和父類中存在同名成員時(shí),子類將會(huì)屏蔽繼承于父類的同名成員,這種情況被稱為隱藏或重定義。(子類內(nèi)部?jī)?yōu)先使用自己類域的同名成員,外部可使用stu.Person::_name進(jìn)行顯示訪問(wèn))

3、子類和父類中的同名成員函數(shù)并不構(gòu)成函數(shù)重載,因?yàn)樗鼈兯幱诓煌念愑?,子類?huì)隱藏父類同名函數(shù)。

4、父類和子類盡量不要使用同名成員。

五、子類的默認(rèn)成員函數(shù) 1、父、子類中各自的成員處理方式

子類中有兩部分成員,一類是子類原生的成員,另一類是繼承于父類的成員。

對(duì)于原生成員,按照普通類調(diào)用默認(rèn)成員函數(shù)的規(guī)則進(jìn)行處理;對(duì)于繼承于父類的成員,將會(huì)調(diào)用父類中的默認(rèn)成員函數(shù)進(jìn)行處理。(各管各的)

2、需要自己寫默認(rèn)成員函數(shù)的情況

1、父類沒(méi)有默認(rèn)構(gòu)造函數(shù),需要自己顯式寫構(gòu)造。

2、子類存在淺拷貝問(wèn)題,需要自己顯式寫拷貝構(gòu)造和賦值。

3、子類有資源需要釋放,需要自己寫顯式析構(gòu)。

3、子類中默認(rèn)成員函數(shù)的寫法 3.1父類沒(méi)有默認(rèn)構(gòu)造函數(shù),需要在子類的構(gòu)造函數(shù)里補(bǔ)充
class Person
{
public:
	Person(const char* name)
		: _name(name)
	{}
protected:
	string _name; // 姓名
};
class Student : public Person
{
public:
	Student(const char* name = "張三", int num = 10)
		: Person(name)//必須調(diào)用父類的構(gòu)造函數(shù)進(jìn)行初始化
		, _num(num)
	{}
protected:
	int _num; //學(xué)號(hào)
};

父類有提供默認(rèn)構(gòu)造函數(shù)就可以不用在子類寫了。

3.2在子類中顯式寫拷貝構(gòu)造
class Person
{
public:
	Person(const Person& p)//形參:引用切片對(duì)象
		: _name(p._name)
	{}
protected:
	string _name; // 姓名
};
class Student : public Person
{
public:
	Student(const Student& s)
		:Person(s)//切片
		,_num(s._num)
	{}
protected:
	int _num; //學(xué)號(hào)
};

利用切片傳入父類對(duì)象構(gòu)造父類。Student s1(s2),在初始化列表中,利用s2中的父類成員去拷貝構(gòu)造s1中的父類成員。

3.3在子類中顯式寫賦值運(yùn)算符重載
class Person
{
public:
	Person& operator=(const Person& p)
	{
		if (this != &p)
			_name = p._name;
		return *this;
	}
protected:
	string _name; // 姓名
};
class Student : public Person
{
public:
	Student& operator=(const Student& s)
	{
		if (this != &s)//防止自己給自己賦值
		{
			Person::operator=(s);//切片傳入父類賦值運(yùn)算符重載中
			//根據(jù)子類成員進(jìn)行深淺拷貝
			_num = s._num;
		}
		return *this;
	}
protected:
	int _num; //學(xué)號(hào)
};

在子類賦值運(yùn)算符重載中調(diào)用父類賦值運(yùn)算符重載,通過(guò)切片,完成父類成員的賦值。

3.4不需要顯式調(diào)用析構(gòu)函數(shù)

錯(cuò)誤代碼:

~Student()
{
    Person::~Person();
}
//子類析構(gòu)函數(shù)結(jié)束后會(huì)調(diào)用一次父類的析構(gòu)函數(shù)

~Person前必須加類域Person。因?yàn)槲鰳?gòu)函數(shù)的名字會(huì)被編譯器統(tǒng)一處理為destructor(),子類的析構(gòu)函數(shù)和父類的析構(gòu)函數(shù)之間構(gòu)成隱藏,所以這里需要寫明類域。

但是,我們并不需要顯式調(diào)用父類的析構(gòu)函數(shù),因?yàn)槌隽俗宇愇鰳?gòu)函數(shù)的作用域,編譯器會(huì)自動(dòng)調(diào)用父類的析構(gòu)。手動(dòng)調(diào)用父類析構(gòu)將會(huì)造成重復(fù)析構(gòu)。

六、繼承和友元、靜態(tài)成員的關(guān)系

1、友元關(guān)系不能被繼承

2、父類中的靜態(tài)成員也會(huì)被繼承,但是整個(gè)繼承關(guān)系中共用這個(gè)靜態(tài)成員

七、菱形繼承和菱形的虛擬繼承 1、菱形繼承

從上圖可以看出,Assistant中會(huì)有兩份Person成員,調(diào)用時(shí)存在二義性和數(shù)據(jù)冗余。

2、二義性和數(shù)據(jù)冗余
int main()
{
	// 這樣會(huì)有二義性無(wú)法明確知道訪問(wèn)的是哪一個(gè)
	Assistant a;
	//a._name = "peter";//不能這么寫,因?yàn)閍中有兩個(gè)_name成員,需要指定類域
	// 需要顯示指定訪問(wèn)哪個(gè)父類的成員可以解決二義性問(wèn)題,但是數(shù)據(jù)冗余問(wèn)題無(wú)法解決
	a.Student::_name = "xxx";
	a.Teacher::_name = "yyy";
	return 0;
}

由于Assistant中有兩個(gè)_name成員,直接調(diào)用存在二義性,需要在成員之前指定類域。

_name這個(gè)成員變量有兩個(gè)問(wèn)題不大,畢竟一個(gè)人可以叫蔣靈瑜,在其他場(chǎng)合也可以叫小蔣。但如果這個(gè)成員變量是一個(gè)int _arr[50000]的數(shù)組呢,一個(gè)類中同時(shí)有兩份這么大的數(shù)組,將會(huì)導(dǎo)致數(shù)據(jù)冗余。

3、虛擬繼承解決二義性和數(shù)據(jù)冗余

產(chǎn)生二義性和數(shù)據(jù)冗余的本質(zhì)就是子類繼承了多份相同成員。

解決方法是在“腰部”類增加virtual關(guān)鍵字。

class Person
{
public:
	string _name; // 姓名
};
class Student :virtual public Person
{
protected:
	int _num; //學(xué)號(hào)
};
class Teacher : virtual public Person
{
protected:
	int _id; // 職工編號(hào)
};
class Assistant : public Student, public Teacher
{
protected:
	string _majorCourse; // 主修課程
};
4、virtual關(guān)鍵字解決二義性和數(shù)據(jù)冗余的方法

先來(lái)一段菱形繼承的代碼,_a、_b、_c、_d分別是類A、類B、類C、類D中的原生成員。

class A
{
public:
	int _a;
};
 class B : public A
//class B : virtual public A
{
public:
	int _b;
};
 class C : public A
//class C : virtual public A
{
public:
	int _c;
};
class D : public B, public C
{
public:
	int _d;
};
int main()
{
	D d;
	d.B::_a = 1;
	d._b = 2;
	d.C::_a = 3;
	d._c = 4;
	d._d = 5;
	return 0;
}
4.1未使用virtual關(guān)鍵字

通過(guò)調(diào)用內(nèi)存,會(huì)發(fā)現(xiàn)對(duì)象d中存在兩份的_a,存在二義性和數(shù)據(jù)冗余。

4.2使用virtual關(guān)鍵字

當(dāng)使用了虛擬繼承,通過(guò)調(diào)用內(nèi)存,發(fā)現(xiàn)對(duì)象d中僅有一份_a,但是繼承于B類和C類的_b和_c上方多了一串地址,再次要通過(guò)內(nèi)存查找這串地址,發(fā)現(xiàn)這串地址之后的位置存放一個(gè)數(shù)字0x14,這個(gè)數(shù)字就是繼承于B的成員到_a的偏移量,通過(guò)這個(gè)偏移量,對(duì)象d便能到d.B::_a。這樣就解決了菱形繼承成員冗余的問(wèn)題。

這里的A叫做虛基類,在對(duì)象d中,將虛基類的成員放到一個(gè)公共的位置,繼承的B、C類需要找到A的成員,通過(guò)虛基表中的偏移量進(jìn)行計(jì)算。我們看到虛基表中第一行還空置了4個(gè)字節(jié),這塊空間存放的也是一個(gè)偏移量,它用于尋找d對(duì)象中的虛函數(shù)指針表。

實(shí)際使用時(shí),盡量不要使用用菱形繼承,因?yàn)樗举|(zhì)就是C++設(shè)計(jì)的一個(gè)坑!

4.3虛繼承+重寫問(wèn)題

1、如果A類中還存在一個(gè)虛函數(shù),那么對(duì)象d會(huì)在_a后面存放虛函數(shù)指針表;

2、如果A類中存在一個(gè)虛函數(shù),并且B、C類均對(duì)這個(gè)虛函數(shù)進(jìn)行了重寫,那么D類中必須對(duì)這個(gè)函數(shù)進(jìn)行重寫,否則將會(huì)發(fā)生虛函數(shù)表重命名的問(wèn)題。

八、繼承和組合的區(qū)別

組合也是一種類復(fù)用的手段。

1、組合的使用場(chǎng)景

適用組合的代碼:輪胎和車的關(guān)系

class Tire
{
protected:
   string _brand = "Michelin"; ?// 品牌
   size_t _size = 18; ? ? ? ? // 尺寸
};
 ? 
class Car{
protected:
    string _colour = "白色"; // 顏色
    string _num = "xxxxx"; // 車牌號(hào)
    Tire _t; // 輪胎
}; ?
2、繼承和組合的區(qū)別

public繼承是一種is-a的關(guān)系,每個(gè)子類對(duì)象都是一個(gè)父類對(duì)象,例如“學(xué)生”是“人”(子類學(xué)生,父類人)

組合是一種has-a的關(guān)系,B組合了A,每個(gè)B對(duì)象中都有一個(gè)A,例如“車”包含“輪胎”

如果兩個(gè)類既可以是is-a,又可以是has-a的關(guān)系,那么優(yōu)先使用組合。

繼承是一種白盒復(fù)用,父類內(nèi)部的細(xì)節(jié)對(duì)子類可見(jiàn),破壞了封裝。子類將會(huì)繼承父類的公有和保護(hù)成員,一旦父類修改了這些成員的實(shí)現(xiàn),將會(huì)影響子類的功能。子類和父類之間的依賴關(guān)系強(qiáng),耦合度高。

組合是一種黑盒復(fù)用,父類內(nèi)部的細(xì)節(jié)對(duì)子類不可見(jiàn),子類僅可使用父類的公有成員,只要父類的公有成員的實(shí)現(xiàn)細(xì)節(jié)不變,子類影響較小。父子之間沒(méi)有很強(qiáng)的依賴關(guān)系,耦合度較低。

你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級(jí)服務(wù)器適合批量采購(gòu),新人活動(dòng)首月15元起,快前往官網(wǎng)查看詳情吧

本文標(biāo)題:【C++】繼承-創(chuàng)新互聯(lián)
網(wǎng)頁(yè)地址:http://aaarwkj.com/article8/jdgop.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供微信公眾號(hào)、動(dòng)態(tài)網(wǎng)站軟件開(kāi)發(fā)、網(wǎng)站收錄、用戶體驗(yàn)外貿(mào)網(wǎng)站建設(shè)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都網(wǎng)頁(yè)設(shè)計(jì)公司
日韩高清精品视频在线| 国产91精品激烈高潮白浆| 国产精品五月婷婷六月丁香| 日本一区二区三区在线观看视频| 久久这里只有精品蜜桃| 黑丝美女大战白丝美女| 国产亚洲精品一区在线| 日韩中文字幕免费一区二区| 亚洲少妇精品视频在线| 精品国产欧美亚洲91| 成人黄片免费在线播放| 日本不卡一二三区在线观看| 成人在线观看av毛片| 午在线亚洲男人午在线| 亚洲国产欧美在线人成人| 欧美精品黄片免费在线观看| 欧美日韩亚洲中文国产| 亚洲国产欧美日韩在线一区| 日韩一二三区免费不卡视频| 精品国产第一区二区三区| 成年人午夜看片免费网站| 日本成人一区二区三区视频| 91精品国产高清91久久久久久| 成人激情视频在线观看| 亚洲欧美另类重口国产| 久久精品国产亚洲熟女| 色噜噜男人的天堂av| 精品一级人片内射视频| 国产午夜18久久久| 国产在线精彩视频自拍| 性色乱码一区二区三区| 国产夫妻自拍一级黄片| 国产高清毛片区1区二区三区 | 深夜日本福利在线观看| 91精品国产色综合久久不| 日韩中文字幕专区在线| 九九在线视频免费观看精品视频 | 尤物视频在线观看官网| 亚洲精品日韩一区二区| 九九热这里只有免费精品| 日本成人在线播放网站|