日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

C/C++学习----第二章 继承和派生

發(fā)布時間:2025/3/15 53 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C/C++学习----第二章 继承和派生 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

第二章 繼承和派生

2.1 派生

派生類或派生類的使用者均不能訪問基類的私有數(shù)據(jù)成員;對于基類的公有成員的訪問,如果派生的方式不同,訪問的權(quán)限也不同。派生時,不指明派生類型的,按私有派生進行派生。

<1>私有派生

由私有派生得到的派生類,對基類的公有成員只能是私有繼承,也就是基類的所有公有成員只能成為派生類的私有成員,這些私有成員只能被派生類的成員函數(shù)訪問,派生類的使用者無權(quán)訪問。此時,基類中的保護段成員也成為派生類的私有成員。

如果希望基類中的某些公有成員、保護成員在私有派生類中也是公有、保護的,使得派生類和派生類的使用者可以訪問它,則可以在派生類中的公有段或保護段中說明這些成員,并在成員名前綴上“類名::”。

class A {

??? int count;

public:

??? A(int i = 0){

?????? count = i; }

??? int getCount(){

?????? return count; }

};

?

class B :A{ //私有派生

public:

??? A::getCount; //聲明基類的公有成員為派生類的公有成員

/*protected:

??? A::getCount; */ //聲明基類的公有成員為派生類的保護成員

};

?

void main()

{

??? B b;??

??? int num = b.getCount();

}

聲明基類的公有成員為派生類的公有成員,只需要注明類名和函數(shù)名,不需要聲明函數(shù)參數(shù)和返回值,因為該函數(shù)在基類中已經(jīng)聲明過。

私有段中不能進行聲明。派生類中有與基類相同的函數(shù)時,這種聲明是無效的,派生對象調(diào)用的函數(shù)是派生類中的,而不是基類的。在派生類公有段中聲明基類的構(gòu)造函數(shù),如果基類構(gòu)造函數(shù)(重載情況下)同在公有段中,則基類的構(gòu)造函數(shù)成為派生類中的公有成員;如果基類構(gòu)造函數(shù)處于不同的段中,系統(tǒng)將根據(jù)派生類構(gòu)造函數(shù)調(diào)用基類構(gòu)造函數(shù)的使用,決定這種聲明的有效性。

?

Class A {

protected:

??? int count;

??? void print1();

public:

??? int num;

??? void print();

??? A();

??? A(int i);

};

?

class B: A{

protected:

??? A::count;

??? A::print1;

public:

??? B();

??? void print();

??? //A::count; //error不能同時聲明

??? A::A;?

??? A::num;

??? A::print; //聲明無效

};

class A {

protected:

??? A(int i);

public:???

??? A();

};

?

class B: A{

public:

??? B():A(){

??? }

??? A::A;? //public段A()有效

/* B():A(2){

??? }

??? A::A;? */ //protected段A()有效

};

?

<2>公有派生

通過公有派生得到派生類,基類中的公有成員在派生類中仍然是公有成員,基類中的保護段成員在派生類中仍然是保護成員。

<3>保護派生

通過公有派生得到派生類,基類中的公有成員和保護段成員,在派生類中是保護成員。

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

2.2.1派生類構(gòu)造函數(shù)和析構(gòu)函數(shù)的定義原則

在以下情況下必須定義派生類的構(gòu)造函數(shù)

??? <1>派生類本身需要構(gòu)造函數(shù)

<2>在定義派生類對象時,其相應(yīng)的基類需要調(diào)用帶參數(shù)的構(gòu)造函數(shù)。

構(gòu)造函數(shù)格式:

派生類構(gòu)造函數(shù)(參數(shù)):基類構(gòu)造函數(shù)(參數(shù)),對象成員1構(gòu)造函數(shù)(參數(shù)),。。。對象成員n構(gòu)造函數(shù)(參數(shù)) { //基類和對象成員構(gòu)造函數(shù)的排放順序不分先后

}

如果基類使用缺省的構(gòu)造函數(shù)或不帶參數(shù)的構(gòu)造函數(shù),則在派生類中定義構(gòu)造函數(shù)時可略去“:基類構(gòu)造函數(shù)(參數(shù))”;如果派生類對象不需要初始化,也不必定義構(gòu)造函數(shù)。

?

派生類的析構(gòu)函數(shù)的定義與基類沒有關(guān)系。

如果基類、成員類和派生類都有構(gòu)造函數(shù),執(zhí)行順序分別是先基類、再對象成員、后派生;析構(gòu)函數(shù)時的執(zhí)行順序正好相反,先派生、再對象成員、后基類。

class A {

??? int count;

public:

??? A(int i = 0){

?????? count = i;

??? }

?????? ~A(){

??? }

};

?

class B{

public:

??? B(char *str){

?????? memset(s, 0, 20);

?????? strcpy(s, str);

??? }

~B(){

??? }

private:

??? char s[20];

};

?

class C :A{

public:

??? C(int num);

~C(){

??? }

private:

??? int number;

??? B b;

};

C::C(int num):b("CHINA"),A(num){

??? number = num;

}

void main(void )

{

??? C c(100);? //先A(num),再b("CHINA"),最后C::C(int num)

} //析構(gòu)時,先~C(),再~B(),最后~A()

2.2.2虛析構(gòu)函數(shù):

c++語言標準關(guān)于虛析構(gòu)函數(shù)的闡述:當通過基類的指針去刪除派生類的對象,而基類又沒有虛析構(gòu)函數(shù)時,結(jié)果將是不可確定的。實際運行時經(jīng)常發(fā)生的是,派生類的析構(gòu)函數(shù)永遠不會被調(diào)用。聲明析構(gòu)函數(shù)為虛就會調(diào)用基類和派生類的析構(gòu)函數(shù)。

#include <iostream.h>

class Base

{

? public:

??? virtual ~Base() { cout<< "~Base" << endl ; }

};

class Derived : public Base

{

? public:

??? virtual ~Derived() { cout<< "~Derived" << endl ; }

};

?

void main(void)

{

??? Base * pB = new Derived;? // upcast

??? delete pB; //對象內(nèi)存釋放時,DerivedBase的析構(gòu)函數(shù)都會被調(diào)用。

}

輸出結(jié)果為:

??? ~Derived

??? ~Base

如果析構(gòu)函數(shù)不為虛,那么輸出結(jié)果為

~Base

2.3 派生類對基類私有成員的訪問

在公有派生和私有派生中,繼承類都不能直接訪問基類的私有成員。繼承類訪問基類的私有成員的方法有以下兩種方法:

<1>在基類中增加保護類成員

將基類私有成員中需要提供給派生類訪問的部分定義為保護段成員。基類的保護類成員可以被派生類(無論公有派生、保護派生還是私有派生)訪問,但外界對象不能訪問。

class A {

protected:

??? int count;

public:

??? A(int i = 0){

?????? count = i;

??? }

??? void print(){

?????? cout << count;

??? }

};

?

class B:public A{

??? int num;

public:

??? B(int i){ num = i;}

??? void print(){

?????? cout << count << " " << num; //公有繼承派生類訪問基類的保護成員

??? }

};

?

class C :B{

public:

??? C(): B(10){ }

??? void print(){

?????? cout << count; //私有繼承的派生類訪問基類的保護成員

??? ??? //cout << num; //私有繼承的派生類不能訪問基類的私有成員

??? }

};

?

void main()

{

??? B b(4);

??? C c;??

??? b.print();

??? c.print();

}

?

<2>將需要訪問基類私有成員的派生類成員函數(shù)聲明為基類的友元

在基類中增加保護類成員的方法,存在一個弊端,多重公有繼承或保護繼承得到的派生類,仍然可以訪問原基類的保護段成員。可以通過將需要訪問基類私有成員的派生類成員函數(shù)聲明為基類的友元的方法,使得派生類中的指定成員函數(shù)函數(shù)可以訪問基類的私有成員,其他的成員函數(shù)則不能訪問基類的私有成員。

通過友員訪問基類的私有成員,這種訪問不是經(jīng)常的,但是必要的。否則,需要類提供足夠的成員函數(shù)。友元的使用使得C++中的數(shù)據(jù)封裝性受到削弱,導(dǎo)致程序的維護性變差(慎用)。

??? 聲明為某個類的友元的外界對象既可以是另一個類的成員函數(shù),也可以是不屬于任何類的一個函數(shù),還可以是某個類(此時,該類中的所有成員函數(shù)都成為友元)。設(shè)置友元的首要目的是可以使友元函數(shù)訪問(使用或改變)某類的私有成員。

??? 友元的聲明可以放在類的公有部分,也可以放在類的私有部分。

??? class circle;

class point {

??? int x, y;

public:

??? point(int x, int y);

??? friend void print(const point p); //聲明不屬于任何類的函數(shù)為友元函數(shù)

??? friend class circle; //聲明某類.為友元類

??? friend void circle::getCircleCenter(int &x, int &y); //聲明某類的函數(shù)為友元函數(shù),該函數(shù)可以訪問point的私有成員x和y

}

?

說明:友元函數(shù)雖然可以訪問類對象的私有成員,但是它沒有this指針,在某一時刻究竟是應(yīng)該訪問哪一個對象的私有成員,很難確定。可以通過向友元函數(shù)傳遞對象的辦法,顯式地確定對象。

友元關(guān)系是“給予”的,而不是“索取”的。也就是說,如果類B是類A的友元類,類A中必須聲明類B是類A的友元類。友元關(guān)系是不對稱且不傳遞的。

?

2.4 虛基類

P part(of A)

?

?

P part(of B)

?

?

C part

C

A

B

P

P

C

A

B

P


??? 在如下左圖所示的多層繼承類中,P兩次成為類C的間接基類,此時,C類對象中有兩個類P的對象:由A繼承的P和由B繼承的P,C類對象的內(nèi)存排列如中圖所示:

??? 虛基類:當在多條繼承路徑上有一個公共的基類,在這些路徑中的某幾條路徑匯合處,這個公共基類會產(chǎn)生多個實例,如果需要只保存基類的一個實例,可以將這個公共基類聲明為虛基類。虛基類的聲明如下表右側(cè)所示:

非虛基類的多重繼承

class P

{

public:

??? int next;

};

class A: public P

{

};

class B: public P

{

};

class C: public A, public B

{

public:

??? void set( int i);

};

void C::set(int i)

{

??? next = i;? //具有二義性

}

?

虛基類的多重繼承

class P

{

public:

??? int next;

};

class A: virtual public P

{

};

class B: virtual public P

{

};

class C: public A, public B

{

public:

??? void set( int i);

};

void C::set(int i)

{

??? next = i;? //無二義性

}

?

?

虛基類構(gòu)造函數(shù)的調(diào)用規(guī)則:

<1>同一層次中虛基類的構(gòu)造函數(shù)在非虛基類之前調(diào)用

<2>同一層次中包含多個虛基類,虛基類構(gòu)造函數(shù)按照他們的說明順序調(diào)用

<3>若虛基類由非虛基類派生,則遵守先調(diào)用基類構(gòu)造函數(shù),再調(diào)用派生類構(gòu)造函數(shù)。

??? 例:

base2

base2

base虛基類

level1

level2虛基類

toplevel


如下所示的類繼承關(guān)系:

?


建立toplevel類對象top時,構(gòu)造函數(shù)的調(diào)用順序是:

base類

base2類

level2類

base2類

level1類

toplevel類

?

轉(zhuǎn)載于:https://www.cnblogs.com/java201408/archive/2006/10/27/3901062.html

總結(jié)

以上是生活随笔為你收集整理的C/C++学习----第二章 继承和派生的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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