日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > c/c++ >内容正文

c/c++

在保护继承中基类的共有成员_C++学习大纲:继承方式的调整

發(fā)布時(shí)間:2023/12/15 c/c++ 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 在保护继承中基类的共有成员_C++学习大纲:继承方式的调整 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

C++ 繼承方式的調(diào)整

在任何繼承方式中,除了基類的private成員外,都可以在派生類中分別調(diào)整其訪問(wèn)控制。

調(diào)整格式

[public: | protected: | private: ] :: ;

class A

{

public:

void f1();

void f2();

void f3();

protected:

void g1();

void g2();

void g3();

}

class B: private A

{

public:

A::f1;//把f1調(diào)整為public

A::g1;//把g1調(diào)整為public,是否允許弱化基類的訪問(wèn)控制要視具體的實(shí)現(xiàn)而定

protected:

A::f2;//把f2調(diào)整為protected

A::g2;//把g2調(diào)整為protected

}

class C: class B

{

public:

void h()

{

f1(); f2(); g1(); g2();//OK

f3(); g3(); //Error,此時(shí)f3,g3是基類B的private成員

}

}

————————————————

C++繼承及其特點(diǎn)

繼承

繼承機(jī)制是面向?qū)ο蟪绦蛟O(shè)計(jì),使代碼可以復(fù)用最重要手段,它允許在保持原有類的基礎(chǔ)上進(jìn)行擴(kuò)展,增加功能,這樣產(chǎn)生的類,叫做派生類,被派生類繼承的類叫做基類。繼承呈現(xiàn)了面向?qū)ο蟪绦蛟O(shè)計(jì)的層次結(jié)構(gòu)。體現(xiàn)了由簡(jiǎn)單到復(fù)雜的認(rèn)知過(guò)程。

繼承方式

派生類名字: 繼承權(quán)限:父類的名字

例如:已存在類class A

那么派生類定義為

class Derived: public A

繼承權(quán)限三種格式

繼承的權(quán)限跟類中成員的權(quán)限一樣,有三種權(quán)限

public. protected. pritave

默認(rèn)派生類的繼承方式為私有繼承方式

如果基類為class,派生類默認(rèn)繼承方式私有

如果基類為struct,派生類默認(rèn)繼承方式為共有

派生類定義方式

//Base //基類 父類

//Derived //派生類 子類

class Base

{

public:

int _b;

};

class Derived : public Base//派生類: 繼承方式 基類

{

public:

int _d;

};

繼承類型

基類的成員的三種類型,繼承到派生類。保護(hù)的類型,繼承的子類也是保護(hù)類型,在類外不可訪問(wèn)。類內(nèi)可以。非本類不可訪問(wèn)。私有成員在派生類中不可訪問(wèn)。

public(公有方式)

子類Derived繼承Base父類的數(shù)據(jù)。

共有的繼承方式,可以訪問(wèn)父類的共有成員與保護(hù)成員。但是無(wú)法訪問(wèn)私有成員。

基類中public類的 在 子類中也是public

基類中protected類的成員 在 子類中也是 protected

基類中私有成員,仍然歸父類私有,雖然子類繼承,但是無(wú)法訪問(wèn)。但是可以調(diào)用父類中共有的方法來(lái)訪問(wèn)。

protected(保護(hù)方式)

保護(hù)的繼承方式

基類中:共有的權(quán)限 如果是保護(hù)的繼承方式, 到了子類中,已經(jīng)從public類改變?yōu)閜rotected類。

基類中保護(hù)的成員在子類中訪問(wèn)的權(quán)限不變。

基類中的私有成員, 子類繼承下來(lái)了,但是就是用不了。

派生類里可以訪問(wèn) 保護(hù)類成員。 類外不行。私有類只能本類中訪問(wèn)。

private(私有方式)

私有的繼承方式,基類中所有的成員變量/函數(shù),在派生類中全部變?yōu)樗接袑傩浴?/p>

繼承的特點(diǎn)

對(duì)象模型: 類中成員變量在內(nèi)存中的布局形式(非靜態(tài)成員變量)

class Base

{

public:

int _a;

int _b;

int _c;

};

class Derived : public Base

{

public:

int a;

int b;

int c;

};

以上的基類與派生類在對(duì)象存儲(chǔ)形式為:

派生類與基類的關(guān)系

共有的繼承方式,可以將基類對(duì)象,當(dāng)做是派生類對(duì)象。

使用角度:所有用到基類的地方,都可以用派生類來(lái)代替。

保護(hù)的繼承方式,protected/private: 子類—基類 相當(dāng)于has-a的關(guān)系

相當(dāng)于在子類中創(chuàng)建了一個(gè)基類對(duì)象,基類擁有自己的作用域以及對(duì)成員的保護(hù)權(quán)限。

基類/派生類賦值:切片/切割

子類可以給父類賦值。反過(guò)來(lái)則不行。(這種方式叫切片/切割)

子類本身就是父類的延伸,因此子類中擁有父類擁有的東西。

派生類給基類賦值時(shí),可以將自己切開(kāi),將上半部分的name賦值給基類對(duì)象。這種方式叫切片/切割

切片/切割一個(gè)天然的行為,并沒(méi)有伴隨著隱式的類型轉(zhuǎn)換,如下證實(shí):

class Base

{

public:

int _a;

int _b;

int _c;

};

class Derived : public Base

{

public:

int a;

int b;

int c;

};

int main()

{

Base B;

Derived D;

B = D;

Base& b = D;

//基類引用對(duì)象引用派生類是沒(méi)有問(wèn)題的。這個(gè)引用變量只能訪問(wèn)到屬于基類的數(shù)據(jù)

//此時(shí)沒(méi)有發(fā)生類型轉(zhuǎn)換,引用的是派生類切出來(lái)的基類對(duì)象,不是類型轉(zhuǎn)換后的數(shù)據(jù)。

int a = 1;

double d = i;//這里發(fā)生隱式類型轉(zhuǎn)換,但是不影響,因?yàn)檫@只是用常量給變量賦值

//double& d1 = i;//因?yàn)榘l(fā)生隱式類型轉(zhuǎn)換時(shí),會(huì)產(chǎn)生一個(gè)臨時(shí)變量

//此時(shí)的double類型的引用變量,引用的是i類型轉(zhuǎn)換后的臨時(shí)變量的值

//臨時(shí)變量具有常屬性,因此必須將引用類型用const修飾

//與常量的屬性保持一致,才可以通過(guò)編譯。

const double& d1 = i;//此時(shí)可以通過(guò)編譯。

}

基類 = 派生類:

基類訪問(wèn)派生類中基類需要的數(shù)據(jù),基類指針可以指向派生類對(duì)象。這時(shí)的指針可以訪問(wèn)基類的成員。基類的引用,可以引用派生類對(duì)象。這是也只是可以訪問(wèn)基類的數(shù)據(jù)。

派生類 = 基類:

基類對(duì)象不能強(qiáng)轉(zhuǎn)為派生類對(duì)象,賦值給派生類。賦值時(shí),派生類會(huì)訪了基類中沒(méi)有的數(shù)據(jù), 會(huì)造成越界訪問(wèn)。發(fā)生錯(cuò)誤。

派生類指針或引用不可以指向或引用基類對(duì)象??赡軙?huì)發(fā)生越界訪問(wèn),所以不允許指向或者引用基類。如果給基類進(jìn)行強(qiáng)轉(zhuǎn),將基類引用強(qiáng)轉(zhuǎn)為派生類,強(qiáng)行訪問(wèn)派生類對(duì)象,訪問(wèn)到不允許訪問(wèn)的內(nèi)容,直接出錯(cuò)。除非這個(gè)基類對(duì)象的指針之前就是指向派生類的指針。

同名隱藏

基類中繼承下來(lái)的函數(shù),與派生類中的同名函數(shù)不能形成重載,而且同名函數(shù)還會(huì)發(fā)生沖突。如果訪問(wèn)相同名稱的函數(shù),派生類中只能調(diào)用自己類中的函數(shù)或者成員。如果想在派生類中訪問(wèn)基類中的同名(成員函數(shù)||成員變量)。只能通過(guò)加基類類作用域的方式去訪問(wèn)相同名稱的基類成員。

d.Base::fun();

同名函數(shù)不能形成重載,因?yàn)楹瘮?shù)重載的條件就是同名函數(shù)必須要在同一作用域,盡管基類與派生類函數(shù)名相同但參數(shù)信息不同, 他們沒(méi)有在同一個(gè)作用域,因此不能形成重載。誤當(dāng)做重載函數(shù)調(diào)用時(shí),肯定出錯(cuò)。

其實(shí)編譯器在編譯期間會(huì)為基類和派生類成員加上對(duì)應(yīng)的作用域限定符,派生類的成員前會(huì)加上派生類的作用域限定符,基類的成員會(huì)加上基類的作用域限定符。

Base::基類成員 Derived::派生類成員

派生類對(duì)象構(gòu)造函數(shù)

派生類對(duì)象構(gòu)造時(shí),先調(diào)用派生類構(gòu)造函數(shù),在派生類構(gòu)造函數(shù)的初始化列表中會(huì)調(diào)用基類的構(gòu)造函數(shù),在進(jìn)入派生類對(duì)象的函數(shù)體之前,會(huì)先在初始化列表中完成派生類中成員的初始化,而這個(gè)初始化列表中就有基類的初始化,因此它會(huì)先初始化基類中成員(構(gòu)造基類成員,調(diào)用基類的構(gòu)造函數(shù)),之后再初始化派生類的成員。

默認(rèn)的派生類構(gòu)造函數(shù)只會(huì)調(diào)用基類的默認(rèn)構(gòu)造函數(shù)。所以基類的構(gòu)造函數(shù)如果是定義的有參數(shù)的,這時(shí)必須在派生類的構(gòu)造函數(shù)初始化列表中給出定義。否則構(gòu)造派生類對(duì)象時(shí),找不到默認(rèn)的基類構(gòu)造函數(shù),代碼不能編譯。

派生類的析構(gòu)函數(shù)

(先析構(gòu)自己的,在最后一個(gè)括號(hào)處調(diào)用基類的析構(gòu)函數(shù))

如果要銷毀派生類的對(duì)象,則需要掉用派生類析構(gòu)函數(shù)來(lái)清理派生類對(duì)象中的資源,在派生類析構(gòu)函數(shù)的最后,需要調(diào)用基類的析構(gòu)函數(shù),以完成基類部分資源的銷毀。

final修飾的類

final修飾的類,不能被繼承

將類的構(gòu)造函數(shù)定義為私有的, 則變?yōu)椴豢衫^承的類。(C++11)中 被final修飾的類,不能被繼承。

繼承與友元函數(shù)

友元關(guān)系不能繼承,基類友元不能訪問(wèn)子類私有和保護(hù)成員。因?yàn)橛言瘮?shù)不是類的成員,所以不能繼承?;惖挠言瘮?shù)因此無(wú)法訪問(wèn)派生類的任何成員。

派生類的友元函數(shù),不能訪問(wèn)基類的私有成員,如果是私有的繼承方式,那么基類的所有成員都不能訪問(wèn)。就跟派生類的訪問(wèn)權(quán)限一致,派生類可以訪問(wèn)到的基類對(duì)象,友元函數(shù)也能訪問(wèn)到。

靜態(tài)成員

靜態(tài)成員變量可以被繼承。并且派生類與基類公用這個(gè)靜態(tài)成員。

多繼承

多繼承方式:

class B1; class B2; //已有的類

class D: public B1,public B2;

B1;

B2;

D;

先繼承的基類在上,后繼承的基類在下, 派生類在最下。

菱形繼承模型:

虛擬繼承

虛擬繼承

class D: virtual public B//關(guān)鍵字 virtual

1

為了解決菱形繼承中的二義性問(wèn)題,大佬們?cè)O(shè)計(jì)出了虛擬繼承。虛擬繼承的派生類中,不管派生類中有多少個(gè)公用的基類,都公用一個(gè)基類。因此在派生類中,前4個(gè)字節(jié)首先存了一個(gè)指針,這個(gè)指針指向一個(gè)類似數(shù)組的區(qū)域,里面裝著要訪問(wèn)基類對(duì)象時(shí),該指針要偏移的偏移量。細(xì)節(jié)如下:

虛擬繼承存儲(chǔ)

虛擬繼承的派生類,存儲(chǔ)方式會(huì)先存放派生類對(duì)象,將基類對(duì)象放在后面存放。

代碼表現(xiàn)

#include

using namespace std;

class A

{

public:

int a;

};

class B:virtual public A

{

public:

int b;

};

class C:virtual public A

{

public:

int c;

};

class D:public B, public C

{

public:

int d;

};

int main()

{

D d;

d.B::a = 2;

d.C::a = 1;

d.b = 3;

d.c = 4;

d.d = 5;

cout << sizeof(d) << endl;

}

內(nèi)存中體現(xiàn)

如果有不對(duì)的地方,希望大佬批評(píng)。

————————————————

通過(guò)分享實(shí)用的計(jì)算機(jī)編程語(yǔ)言干貨,推動(dòng)中國(guó)編程到2025年基本實(shí)現(xiàn)普及化,使編程變得全民皆知,最終實(shí)現(xiàn)中國(guó)編程之崛起,這里是中國(guó)編程2025,感謝大家的支持。

原文鏈接:https://blog.csdn.net/haitaolang/article/details/70844494

原文鏈接:https://blog.csdn.net/qq_41804778/article/details/81561547

總結(jié)

以上是生活随笔為你收集整理的在保护继承中基类的共有成员_C++学习大纲:继承方式的调整的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。