面向?qū)ο蟪绦蛟O(shè)計(jì)(C++):第7章 繼承與派生_第1頁(yè)
面向?qū)ο蟪绦蛟O(shè)計(jì)(C++):第7章 繼承與派生_第2頁(yè)
面向?qū)ο蟪绦蛟O(shè)計(jì)(C++):第7章 繼承與派生_第3頁(yè)
面向?qū)ο蟪绦蛟O(shè)計(jì)(C++):第7章 繼承與派生_第4頁(yè)
面向?qū)ο蟪绦蛟O(shè)計(jì)(C++):第7章 繼承與派生_第5頁(yè)
已閱讀5頁(yè),還剩98頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、第七章 繼承與派生目錄7.1 類(lèi)的繼承與派生7.2 訪(fǎng)問(wèn)控制7.3 類(lèi)型兼容規(guī)則7.4 派生類(lèi)的構(gòu)造、析構(gòu)函數(shù)7.5 派生類(lèi)成員的標(biāo)識(shí)與訪(fǎng)問(wèn)7.6 程序?qū)嵗酶咚瓜シń饩€(xiàn)性方程組7.7 綜合實(shí)例個(gè)人銀行賬戶(hù)管理程序7.8 深度探索7.9 小結(jié) 27.1 類(lèi)的繼承與派生保持已有類(lèi)的特性而構(gòu)造新類(lèi)的過(guò)程稱(chēng)為繼承。在已有類(lèi)的基礎(chǔ)上新增自己的特性而產(chǎn)生新類(lèi)的過(guò)程稱(chēng)為派生。被繼承的已有類(lèi)稱(chēng)為基類(lèi)(或父類(lèi))。派生出的新類(lèi)稱(chēng)為派生類(lèi)。37.1 類(lèi)的繼承與派生繼承與派生的目的繼承的目的:實(shí)現(xiàn)代碼重用。派生的目的:當(dāng)新的問(wèn)題出現(xiàn),原有程序無(wú)法解決(或不能完全解決)時(shí),需要對(duì)原有程序進(jìn)行改造。47.1 類(lèi)的繼承

2、與派生 7.1.1 派生與繼承的實(shí)例7.1.2派生類(lèi)的聲明class 派生類(lèi)名:繼承方式 基類(lèi)名 成員聲明;例如:class Derived: public Base1, private Base2public:Derived ();Derived ();57.1 類(lèi)的繼承與派生 7.1.2 派生類(lèi)的定義繼承方式一個(gè)派生類(lèi),可以同時(shí)有多個(gè)基類(lèi),這種情況稱(chēng)為多繼承一個(gè)派生類(lèi)只有一個(gè)直接基類(lèi)的情況,稱(chēng)為單繼承。直接參與派生出某類(lèi)的基類(lèi)稱(chēng)為直接基類(lèi),基類(lèi)的基類(lèi)甚至更高層的基類(lèi)稱(chēng)為間接基類(lèi)。派生類(lèi)成員是指除了從基類(lèi)繼承來(lái)的所有成員之外,新增加的數(shù)據(jù)和函數(shù)成員。67.1 類(lèi)的繼承與派生 7.1.2 派生

3、類(lèi)的定義7.1.3 派生類(lèi)生成過(guò)程派生新類(lèi)經(jīng)歷了三個(gè)步驟:吸收基類(lèi)成員吸收基類(lèi)成員之后,派生類(lèi)實(shí)際上就包含了它的全部基類(lèi)中除構(gòu)造和析構(gòu)函數(shù)之外的所有成員。改造基類(lèi)成員如果派生類(lèi)聲明了一個(gè)和某基類(lèi)成員同名的新成員(如果是成員函數(shù),則參數(shù)表也要相同,參數(shù)不同的情況屬于重載),派生的新成員就覆蓋了外層同名成員添加新的成員派生類(lèi)新成員的加入是繼承與派生機(jī)制的核心,是保證派生類(lèi)在功能上有所發(fā)展77.1 類(lèi)的繼承與派生7.2 訪(fǎng)問(wèn)控制不同繼承方式的影響主要體現(xiàn)在:派生類(lèi)成員對(duì)基類(lèi)成員的訪(fǎng)問(wèn)權(quán)限通過(guò)派生類(lèi)對(duì)象對(duì)基類(lèi)成員的訪(fǎng)問(wèn)權(quán)限三種繼承方式公有繼承私有繼承保護(hù)繼承基類(lèi)四種訪(fǎng)問(wèn)權(quán)限 公有,私有,保護(hù),不可訪(fǎng)問(wèn)

4、基類(lèi)中的私有成員到繼承類(lèi)中變?yōu)椴豢稍L(fǎng)問(wèn),可以通過(guò)基類(lèi)中德公有接口對(duì)其進(jìn)行訪(fǎng)問(wèn)。公有成員變成私有,保護(hù)變?yōu)楸Wo(hù),不可訪(fǎng)問(wèn)變?yōu)椴豢稍L(fǎng)問(wèn)87.2 訪(fǎng)問(wèn)控制7.2.1 公有繼承(public)基類(lèi)的public和protected成員的訪(fǎng)問(wèn)屬性在派生類(lèi)中保持不變,但基類(lèi)的private成員不可直接訪(fǎng)問(wèn)。派生類(lèi)中的成員函數(shù)可以直接訪(fǎng)問(wèn)基類(lèi)中的public和protected成員,但不能直接訪(fǎng)問(wèn)基類(lèi)的private成員。通過(guò)派生類(lèi)的對(duì)象只能訪(fǎng)問(wèn)基類(lèi)的public成員。97.2 訪(fǎng)問(wèn)控制 7.2.1 公有繼承10例7-1 公有繼承舉例/Point.h#ifndef _POINT_H#define _POIN

5、T_Hclass Point /基類(lèi)Point類(lèi)的定義public:/公有函數(shù)成員void initPoint(float x = 0, float y = 0) this-x = x; this-y = y;void move(float offX, float offY) x += offX; y += offY; float getX() const return x; float getY() const return y; private:/私有數(shù)據(jù)成員float x, y;#endif /_POINT_H7.2 訪(fǎng)問(wèn)控制 7.2.1 公有繼承11例7-1 (續(xù))/Rectangle

6、.h#ifndef _RECTANGLE_H#define _RECTANGLE_H#include Point.hclass Rectangle: public Point /派生類(lèi)定義部分public:/新增公有函數(shù)成員void initRectangle(float x, float y, float w, float h) initPoint(x, y); /調(diào)用基類(lèi)公有成員函數(shù)this-w = w;this-h = h;float getH() const return h; float getW() const return w; private:/新增私有數(shù)據(jù)成員float w,

7、 h;#endif /_RECTANGLE_H7.2 訪(fǎng)問(wèn)控制 7.2.1 公有繼承12例7-1 (續(xù))#include #include using namespace std;int main() Rectangle rect;/定義Rectangle類(lèi)的對(duì)象/設(shè)置矩形的數(shù)據(jù)rect.initRectangle(2, 3, 20, 10);rect.move(3,2);/移動(dòng)矩形位置cout The data of rect(x,y,w,h): endl;/輸出矩形的特征參數(shù)cout rect.getX() , rect.getY() , rect.getW() , rect.getH()

8、 x = x; this-y = y;void move(float offX, float offY) x += offX; y += offY; float getX() const return x; float getY() const return y; private:/私有數(shù)據(jù)成員float x, y;#endif /_POINT_H7.2 訪(fǎng)問(wèn)控制 7.2.2 私有繼承15例7-2 (續(xù))/Rectangle.h#ifndef _RECTANGLE_H#define _RECTANGLE_H#include Point.hclass Rectangle: private Poi

9、nt /派生類(lèi)定義部分public:/新增公有函數(shù)成員void initRectangle(float x, float y, float w, float h) initPoint(x, y); /調(diào)用基類(lèi)公有成員函數(shù)this-w = w;this-h = h;void move(float offX, float offY) Point:move(offX, offY);float getX() const return Point:getX(); float getY() const return Point:getY(); float getH() const return h; fl

10、oat getW() const return w; private:/新增私有數(shù)據(jù)成員float w, h;#endif /_RECTANGLE_H7.2 訪(fǎng)問(wèn)控制 7.2.2 私有繼承16例7-2 (續(xù))#include #include using namespace std;int main() Rectangle rect;/定義Rectangle類(lèi)的對(duì)象rect.initRectangle(2, 3, 20, 10);/設(shè)置矩形的數(shù)據(jù)rect.move(3,2);/移動(dòng)矩形位置cout The data of rect(x,y,w,h): endl;cout rect.getX()

11、 , /輸出矩形的特征參數(shù) rect.getY() , rect.getW() , rect.getH() endl;return 0;7.2 訪(fǎng)問(wèn)控制 7.2.2 私有繼承7.2.3 保護(hù)繼承(protected)基類(lèi)的public和protected成員都以protected身份出現(xiàn)在派生類(lèi)中,但基類(lèi)的private成員不可直接訪(fǎng)問(wèn)。派生類(lèi)中的成員函數(shù)可以直接訪(fǎng)問(wèn)基類(lèi)中的public和protected成員,但不能直接訪(fǎng)問(wèn)基類(lèi)的private成員。通過(guò)派生類(lèi)的對(duì)象不能直接訪(fǎng)問(wèn)基類(lèi)中的任何成員177.2 訪(fǎng)問(wèn)控制 7.2.3 保護(hù)繼承protected 成員的特點(diǎn)與作用對(duì)建立其所在類(lèi)對(duì)象的模

12、塊來(lái)說(shuō),它與 private 成員的性質(zhì)相同。對(duì)于其派生類(lèi)來(lái)說(shuō),它與 public 成員的性質(zhì)相同。既實(shí)現(xiàn)了數(shù)據(jù)隱藏,又方便繼承,實(shí)現(xiàn)代碼重用。187.2 訪(fǎng)問(wèn)控制 7.2.3 保護(hù)繼承19例: protected 成員舉例class A protected:int x;int main() A a;a.x = 5; /錯(cuò)誤7.2 訪(fǎng)問(wèn)控制 7.2.3 保護(hù)繼承20例 (續(xù))class A protected:int x;class B: public Apublic:void function();void B:function() x = 5; /正確7.2 訪(fǎng)問(wèn)控制 7.2.3 保護(hù)繼承

13、7.3 類(lèi)型兼容規(guī)則一個(gè)公有派生類(lèi)的對(duì)象在使用上可以被當(dāng)作基類(lèi)的對(duì)象,反之則禁止。具體表現(xiàn)在:派生類(lèi)的對(duì)象可以隱含轉(zhuǎn)換為基類(lèi)對(duì)象。派生類(lèi)的對(duì)象可以初始化基類(lèi)的引用。派生類(lèi)的指針可以隱含轉(zhuǎn)換為基類(lèi)的指針。通過(guò)基類(lèi)對(duì)象名、指針只能使用從基類(lèi)繼承的成員217.3 類(lèi)型兼容規(guī)則22例7-3 類(lèi)型兼容規(guī)則舉例#include using namespace std;class Base1 /基類(lèi)Base1定義public:void display() const cout Base1:display() endl;class Base2: public Base1 /公有派生類(lèi)Base2定義public

14、:void display() const cout Base2:display() endl;class Derived: public Base2 /公有派生類(lèi)Derived定義public:void display() const cout Derived:display() display();/對(duì)象指針-成員名int main() /主函數(shù)Base1 base1;/聲明Base1類(lèi)對(duì)象Base2 base2;/聲明Base2類(lèi)對(duì)象Derived derived;/聲明Derived類(lèi)對(duì)象fun(&base1);/用Base1對(duì)象的指針調(diào)用fun函數(shù)fun(&base2);/用Base

15、2對(duì)象的指針調(diào)用fun函數(shù)fun(&derived); /用Derived對(duì)象的指針調(diào)用fun函數(shù)return 0;7.3 類(lèi)型兼容規(guī)則運(yùn)行結(jié)果:B1:display()B1:display()B1:display()絕對(duì)不要重新定義繼承而來(lái)的非虛函數(shù)基類(lèi)與派生類(lèi)的對(duì)應(yīng)關(guān)系單繼承派生類(lèi)只從一個(gè)基類(lèi)派生。多繼承派生類(lèi)從多個(gè)基類(lèi)派生。多重派生由一個(gè)基類(lèi)派生出多個(gè)不同的派生類(lèi)。多層派生派生類(lèi)又作為基類(lèi),繼續(xù)派生新的類(lèi)。247.4 派生類(lèi)的構(gòu)造和析構(gòu)函數(shù) 7.4.1 構(gòu)造函數(shù)多繼承時(shí)派生類(lèi)的聲明class 派生類(lèi)名:繼承方式1 基類(lèi)名1,繼承方式2 基類(lèi)名2,.成員聲明;注意:每一個(gè)“繼承方式”,只用

16、于限制對(duì)緊隨其后之基類(lèi)的繼承。257.4 派生類(lèi)的構(gòu)造和析構(gòu)函數(shù) 7.4.1 構(gòu)造函數(shù)多繼承舉例class A public:void setA(int);void showA() const;private:int a;class B public:void setB(int);void showB() const;private:int b;class C : public A, private B public:void setC(int, int, int);void showC() const;private const:int c;267.4 派生類(lèi)的構(gòu)造和析構(gòu)函數(shù) 7.4.1 構(gòu)

17、造函數(shù)多繼承舉例 (續(xù))void A:setA(int x) a=x; void B:setB(int x) b=x; void C:setC(int x, int y, int z) /派生類(lèi)成員直接訪(fǎng)問(wèn)基類(lèi)的/公有成員setA(x); setB(y); c = z;/其他函數(shù)實(shí)現(xiàn)略int main() C obj;obj.setA(5);obj.showA();obj.setC(6,7,9);obj.showC();/ obj.setB(6); 錯(cuò)誤/ obj.showB(); 錯(cuò)誤return 0;277.4 派生類(lèi)的構(gòu)造和析構(gòu)函數(shù) 7.4.1 構(gòu)造函數(shù)繼承時(shí)的構(gòu)造函數(shù)基類(lèi)的構(gòu)造函數(shù)不被

18、繼承,派生類(lèi)中需要聲明自己的構(gòu)造函數(shù)。定義構(gòu)造函數(shù)時(shí),只需要對(duì)本類(lèi)中新增成員進(jìn)行初始化,對(duì)繼承來(lái)的基類(lèi)成員的初始化,自動(dòng)調(diào)用基類(lèi)構(gòu)造函數(shù)完成。派生類(lèi)的構(gòu)造函數(shù)需要給基類(lèi)的構(gòu)造函數(shù)傳遞參數(shù)287.4 派生類(lèi)的構(gòu)造和析構(gòu)函數(shù) 7.4.1 構(gòu)造函數(shù)單一繼承時(shí)的構(gòu)造函數(shù)派生類(lèi)名:派生類(lèi)名(基類(lèi)所需的形參,本類(lèi)成員所需的形參):基類(lèi)名(參數(shù)表)本類(lèi)成員初始化賦值語(yǔ)句;297.4 派生類(lèi)的構(gòu)造和析構(gòu)函數(shù) 7.4.1 構(gòu)造函數(shù)30單一繼承時(shí)的構(gòu)造函數(shù)舉例#includeusing namecpace std;class B public:B();B(int i);B();void print() const

19、;private:int b;7.4 派生類(lèi)的構(gòu)造和析構(gòu)函數(shù) 7.4.1 構(gòu)造函數(shù)31單一繼承時(shí)的構(gòu)造函數(shù)舉例 (續(xù))B:B() b=0;cout Bs default constructor called. endl;B:B(int i) b=i;cout Bs constructor called. endl;B:B() cout Bs destructor called. endl;void B:print() const cout b endl;7.4 派生類(lèi)的構(gòu)造和析構(gòu)函數(shù) 7.4.1 構(gòu)造函數(shù)32單一繼承時(shí)的構(gòu)造函數(shù)舉例 (續(xù))class C: public B public:C(

20、);C(int i, int j);C();void print() const;private:int c;C:C() c = 0;cout Cs default constructor called. endl;C:C(int i,int j): B(i) c = j;cout Cs constructor called. endl;7.4 派生類(lèi)的構(gòu)造和析構(gòu)函數(shù) 7.4.1 構(gòu)造函數(shù)33單一繼承時(shí)的構(gòu)造函數(shù)舉例 (續(xù))C:C() cout Cs destructor called. endl;void C:print() const B:print();cout c endl;int m

21、ain() C obj(5, 6);obj.print();return 0;7.4 派生類(lèi)的構(gòu)造和析構(gòu)函數(shù) 7.4.1 構(gòu)造函數(shù)多繼承時(shí)的構(gòu)造函數(shù)派生類(lèi)名:派生類(lèi)名(參數(shù)表):基類(lèi)名1(基類(lèi)1初始化參數(shù)表), 基類(lèi)名2(基類(lèi)2初始化參數(shù)表), .基類(lèi)名n(基類(lèi)n初始化參數(shù)表) 本類(lèi)成員初始化賦值語(yǔ)句;347.4 派生類(lèi)的構(gòu)造和析構(gòu)函數(shù) 7.4.1 構(gòu)造函數(shù)派生類(lèi)與基類(lèi)的構(gòu)造函數(shù)當(dāng)基類(lèi)中聲明有缺省構(gòu)造函數(shù)或未聲明構(gòu)造函數(shù)時(shí),派生類(lèi)構(gòu)造函數(shù)可以不向基類(lèi)構(gòu)造函數(shù)傳遞參數(shù),也可以不聲明,構(gòu)造派生類(lèi)的對(duì)象時(shí),基類(lèi)的缺省構(gòu)造函數(shù)將被調(diào)用。當(dāng)需要執(zhí)行基類(lèi)中帶形參的構(gòu)造函數(shù)來(lái)初始化基類(lèi)數(shù)據(jù)時(shí),派生類(lèi)構(gòu)造函數(shù)

22、應(yīng)在初始化列表中為基類(lèi)構(gòu)造函數(shù)提供參數(shù)。357.4 派生類(lèi)的構(gòu)造和析構(gòu)函數(shù) 7.4.1 構(gòu)造函數(shù)多繼承且有內(nèi)嵌對(duì)象時(shí)的構(gòu)造函數(shù)派生類(lèi)名:派生類(lèi)名(形參表):基類(lèi)名1(參數(shù)), 基類(lèi)名2(參數(shù)), .基類(lèi)名n(參數(shù)),新增成員對(duì)象的初始化 本類(lèi)成員初始化賦值語(yǔ)句;367.4 派生類(lèi)的構(gòu)造和析構(gòu)函數(shù) 7.4.1 構(gòu)造函數(shù)構(gòu)造函數(shù)的執(zhí)行順序調(diào)用基類(lèi)構(gòu)造函數(shù),調(diào)用順序按照它們被繼承時(shí)聲明的順序(從左向右)。對(duì)成員對(duì)象進(jìn)行初始化,初始化順序按照它們?cè)陬?lèi)中聲明的順序。執(zhí)行派生類(lèi)的構(gòu)造函數(shù)體中的內(nèi)容。377.4 派生類(lèi)的構(gòu)造和析構(gòu)函數(shù) 7.4.1 構(gòu)造函數(shù)38例7-4 派生類(lèi)構(gòu)造函數(shù)舉例#include u

23、sing namespace std;class Base1 /基類(lèi)Base1,構(gòu)造函數(shù)有參數(shù)public:Base1(int i) cout Constructing Base1 i endl; ;class Base2 /基類(lèi)Base2,構(gòu)造函數(shù)有參數(shù)public:Base2(int j) cout Constructing Base2 j endl; ;class Base3 /基類(lèi)Base3,構(gòu)造函數(shù)無(wú)參數(shù)public:Base3() cout Constructing Base3 * endl; ;7.4 派生類(lèi)的構(gòu)造和析構(gòu)函數(shù) 7.4.1 構(gòu)造函數(shù)39例7-4 (續(xù))class D

24、erived: public Base2, public Base1, public Base3 /派生新類(lèi)Derived,注意基類(lèi)名的順序public:/派生類(lèi)的公有成員Derived(int a, int b, int c, int d): Base1(a), member2(d), member1(c), Base2(b) /注意基類(lèi)名的個(gè)數(shù)與順序,/注意成員對(duì)象名的個(gè)數(shù)與順序private:/派生類(lèi)的私有成員對(duì)象Base1 member1;Base2 member2;Base3 member3;int main() Derived obj(1, 2, 3, 4);return 0;7.

25、4 派生類(lèi)的構(gòu)造和析構(gòu)函數(shù) 7.4.1 構(gòu)造函數(shù)運(yùn)行結(jié)果:constructing Base2 2constructing Base1 1constructing Base3 *constructing Base1 3constructing Base2 4constructing Base3 *7.4.2 拷貝構(gòu)造函數(shù)若建立派生類(lèi)對(duì)象時(shí)沒(méi)有編寫(xiě)拷貝構(gòu)造函數(shù),編譯器會(huì)生成一個(gè)隱含的拷貝構(gòu)造函數(shù),該函數(shù)先調(diào)用基類(lèi)的拷貝構(gòu)造函數(shù),再為派生類(lèi)新增的成員對(duì)象執(zhí)行拷貝。若編寫(xiě)派生類(lèi)的拷貝構(gòu)造函數(shù),則需要為基類(lèi)相應(yīng)的拷貝構(gòu)造函數(shù)傳遞參數(shù)。例如:C:C(const C &c1): B(c1) 407.4 派

26、生類(lèi)的構(gòu)造和析構(gòu)函數(shù)7.4.3 析構(gòu)函數(shù)析構(gòu)函數(shù)也不被繼承,派生類(lèi)自行聲明聲明方法與一般(無(wú)繼承關(guān)系時(shí))類(lèi)的析構(gòu)函數(shù)相同。不需要顯式地調(diào)用基類(lèi)的析構(gòu)函數(shù),系統(tǒng)會(huì)自動(dòng)隱式調(diào)用。析構(gòu)函數(shù)的調(diào)用次序與構(gòu)造函數(shù)相反。417.4 派生類(lèi)的構(gòu)造和析構(gòu)函數(shù) 7.4.3 析構(gòu)函數(shù)42例7-5 派生類(lèi)析構(gòu)函數(shù)舉例#include using namespace std;class Base1 /基類(lèi)Base1,構(gòu)造函數(shù)有參數(shù)public:Base1(int i) cout Constructing Base1 i endl; Base1() cout Destructing Base1 endl; ;class

27、 Base2 /基類(lèi)Base2,構(gòu)造函數(shù)有參數(shù)public:Base2(int j) cout Constructing Base2 j endl; Base2() cout Destructing Base2 endl; ;class Base3 /基類(lèi)Base3,構(gòu)造函數(shù)無(wú)參數(shù)public:Base3() cout Constructing Base3 * endl; Base3() cout Destructing Base3 endl; ;7.4 派生類(lèi)的構(gòu)造和析構(gòu)函數(shù) 7.4.3 析構(gòu)函數(shù)43例7-5 (續(xù))class Derived: public Base2, public Ba

28、se1, public Base3 /派生新類(lèi)Derived,注意基類(lèi)名的順序public:/派生類(lèi)的公有成員Derived(int a, int b, int c, int d): Base1(a), member2(d), member1(c), Base2(b) /注意基類(lèi)名的個(gè)數(shù)與順序,注意成員對(duì)象名的個(gè)數(shù)與順序private:/派生類(lèi)的私有成員對(duì)象Base1 member1;Base2 member2;Base3 member3;int main() Derived obj(1, 2, 3, 4);return 0;7.4 派生類(lèi)的構(gòu)造和析構(gòu)函數(shù) 7.4.3 析構(gòu)函數(shù)44例7-5 (

29、續(xù))運(yùn)行結(jié)果:Constructing Base2 2Constructing Base1 1Constructing Base3 *Constructing Base1 3Constructing Base2 4Constructing Base3 *Destructing Base3Destructing Base2Destructing Base1Destructing Base3Destructing Base1Destructing Base27.4 派生類(lèi)的構(gòu)造和析構(gòu)函數(shù) 7.4.3 析構(gòu)函數(shù)同名隱藏規(guī)則當(dāng)派生類(lèi)與基類(lèi)中有相同成員時(shí):若未強(qiáng)行指名,則通過(guò)派生類(lèi)對(duì)象使用的是派生類(lèi)中的

30、同名成員。如要通過(guò)派生類(lèi)對(duì)象訪(fǎng)問(wèn)基類(lèi)中被隱藏的同名成員,應(yīng)使用基類(lèi)名限定。457.5 派生類(lèi)成員的標(biāo)識(shí)與訪(fǎng)問(wèn) 7.5.1 作用域分辨46例7-6 多繼承同名隱藏舉例#include using namespace std;class Base1 /定義基類(lèi)Base1public:int var;void fun() cout Member of Base1 endl; ;class Base2 /定義基類(lèi)Base2public:int var;void fun() cout Member of Base2 endl; ;class Derived: public Base1, public B

31、ase2 /定義派生類(lèi)Derivedpublic:int var;/同名數(shù)據(jù)成員void fun() cout Member of Derived Base2:var = 3;/作用域分辨符標(biāo)識(shí)p-Base2:fun();/訪(fǎng)問(wèn)Base2基類(lèi)成員return 0;7.5 派生類(lèi)成員的標(biāo)識(shí)與訪(fǎng)問(wèn) 7.5.1 作用域分辨二義性問(wèn)題在多繼承時(shí),基類(lèi)與派生類(lèi)之間,或基類(lèi)之間出現(xiàn)同名成員時(shí),將出現(xiàn)訪(fǎng)問(wèn)時(shí)的二義性(不確定性)采用虛函數(shù)(參見(jiàn)第8章)或同名隱藏規(guī)則來(lái)解決。當(dāng)派生類(lèi)從多個(gè)基類(lèi)派生,而這些基類(lèi)又從同一個(gè)基類(lèi)派生,則在訪(fǎng)問(wèn)此共同基類(lèi)中的成員時(shí),將產(chǎn)生二義性采用虛基類(lèi)來(lái)解決。487.5 派生類(lèi)成員的

32、標(biāo)識(shí)與訪(fǎng)問(wèn) 7.5.1 作用域分辨二義性問(wèn)題舉例(1)class A public:void f();class B public:void f();void g();class C: public A, piblic B public:void g();void h();如果定義:C c1;則 c1.f() 具有二義性而 c1.g() 無(wú)二義性(同名隱藏)497.5 派生類(lèi)成員的標(biāo)識(shí)與訪(fǎng)問(wèn) 7.5.1 作用域分辨二義性的解決方法解決方法一:用類(lèi)名來(lái)限定c1.A:f() 或 c1.B:f()解決方法二:同名隱藏在C 中聲明一個(gè)同名成員函數(shù)f(),f()再根據(jù)需要調(diào)用 A:f() 或 B:f()

33、507.5 派生類(lèi)成員的標(biāo)識(shí)與訪(fǎng)問(wèn) 7.5.1 作用域分辨例7-7 多繼承同名隱藏舉例(2)/7_7.cpp#include using namespace std;class Base0 /定義基類(lèi)Base0public:int var0;void fun0() cout Member of Base0 endl; ;class Base1: public Base0 /定義派生類(lèi)Base1 public:/新增外部接口int var1;class Base2: public Base0 /定義派生類(lèi)Base2 public:/新增外部接口int var2;517.5 派生類(lèi)成員的標(biāo)識(shí)與訪(fǎng)問(wèn)

34、 7.5.1 作用域分辨例7-7(續(xù))class Derived: public Base1, public Base2 /定義派生類(lèi)Derived public:/新增外部接口int var;void fun() cout Member of Derived endl; ;int main() /程序主函數(shù)Derived d;/定義Derived類(lèi)對(duì)象dd.Base1:var0 = 2;/使用直接基類(lèi)d.Base1:fun0();d.Base2:var0 = 3;/使用直接基類(lèi)d.Base2:fun0();return 0;527.5 派生類(lèi)成員的標(biāo)識(shí)與訪(fǎng)問(wèn) 7.5.1 作用域分辨派生類(lèi)C的

35、對(duì)象的存儲(chǔ)結(jié)構(gòu)示意圖:var0var1var0var2varBase0類(lèi)成員Base0類(lèi)成員Base1類(lèi)成員Base2類(lèi)成員Derived類(lèi)對(duì)象有二義性:Derived d;d.var0d.Base0:var0無(wú)二義性:d.Base1:var0d.Base2:var0537.5 派生類(lèi)成員的標(biāo)識(shí)與訪(fǎng)問(wèn) 7.5.1 作用域分辨Base0Base1Base2DerivedBase07.5.2 虛基類(lèi)虛基類(lèi)的引入用于有共同基類(lèi)的場(chǎng)合聲明以virtual修飾說(shuō)明基類(lèi)例:class B1:virtual public B作用主要用來(lái)解決多繼承時(shí)可能發(fā)生的對(duì)同一基類(lèi)繼承多次而產(chǎn)生的二義性問(wèn)題.為最遠(yuǎn)的派生

36、類(lèi)提供唯一的基類(lèi)成員,而不重復(fù)產(chǎn)生多次拷貝注意:在第一級(jí)繼承時(shí)就要將共同基類(lèi)設(shè)計(jì)為虛基類(lèi)。547.5 派生類(lèi)成員的標(biāo)識(shí)與訪(fǎng)問(wèn)55例7-8 虛基類(lèi)舉例7.5 派生類(lèi)成員的標(biāo)識(shí)與訪(fǎng)問(wèn) 7.5.2 虛基類(lèi)DerivedBase0:var0:intBase1:var1:intBase2:var2:intvar :intBase0:fun0():voidfun():voidBase1+ var1 : intBase2+ var2 : intDerived+ var : int+ fun() : void Base0+ var0 : int+ fun0() : void56例7-8 (續(xù))#include

37、 using namespace std;class Base0 /定義基類(lèi)Base0public:int var0;void fun0() cout Member of Base0 endl; ;class Base1: virtual public Base0 /定義派生類(lèi)Base1public:/新增外部接口int var1;class Base2: virtual public Base0 /定義派生類(lèi)Base2public:/新增外部接口int var2;7.5 派生類(lèi)成員的標(biāo)識(shí)與訪(fǎng)問(wèn) 7.5.2 虛基類(lèi)57例7-8 (續(xù))class Derived: public Base1, p

38、ublic Base2 /定義派生類(lèi)Derived public:/新增外部接口int var;void fun() cout Member of Derived endl;int main() /程序主函數(shù)Derived d; /定義Derived類(lèi)對(duì)象dd.var0 = 2; /直接訪(fǎng)問(wèn)虛基類(lèi)的數(shù)據(jù)成員d.fun0(); /直接訪(fǎng)問(wèn)虛基類(lèi)的函數(shù)成員return 0;7.5 派生類(lèi)成員的標(biāo)識(shí)與訪(fǎng)問(wèn) 7.5.2 虛基類(lèi)7.5.3 虛基類(lèi)及其派生類(lèi)構(gòu)造函數(shù)建立對(duì)象時(shí)所指定的類(lèi)稱(chēng)為最(遠(yuǎn))派生類(lèi)。虛基類(lèi)的成員是由最派生類(lèi)的構(gòu)造函數(shù)通過(guò)調(diào)用虛基類(lèi)的構(gòu)造函數(shù)進(jìn)行初始化的。在整個(gè)繼承結(jié)構(gòu)中,直接或間接繼

39、承虛基類(lèi)的所有派生類(lèi),都必須在構(gòu)造函數(shù)的成員初始化表中給出對(duì)虛基類(lèi)的構(gòu)造函數(shù)的調(diào)用。如果未列出,則表示調(diào)用該虛基類(lèi)的默認(rèn)構(gòu)造函數(shù)。在建立對(duì)象時(shí),只有最派生類(lèi)的構(gòu)造函數(shù)調(diào)用虛基類(lèi)的構(gòu)造函數(shù),該派生類(lèi)的其他基類(lèi)對(duì)虛基類(lèi)構(gòu)造函數(shù)的調(diào)用被忽略。587.5 派生類(lèi)成員的標(biāo)識(shí)與訪(fǎng)問(wèn)59有虛基類(lèi)時(shí)的構(gòu)造函數(shù)舉例#include using namespace std;class Base0 /定義基類(lèi)Base0public:Base0(int var) : var0(var) int var0;void fun0() cout Member of Base0 endl; ;class Base1: virt

40、ual public Base0 /定義派生類(lèi)Base1public:/新增外部接口Base1(int var) : Base0(var) int var1;class Base2: virtual public Base0 /定義派生類(lèi)Base2public:/新增外部接口Base2(int var) : Base0(var) int var2;7.5 派生類(lèi)成員的標(biāo)識(shí)與訪(fǎng)問(wèn) 7.5.3 虛基類(lèi)及其派生類(lèi)構(gòu)造函數(shù)60有虛基類(lèi)時(shí)的構(gòu)造函數(shù)舉例 (續(xù))class Derived: public Base1, public Base2 /定義派生類(lèi)Derivedpublic:/新增外部接口Deri

41、ved(int var) : Base0(var), Base1(var), Base2(var) int var;void fun() cout Member of Derived endl; ;int main() /程序主函數(shù)Derived d(1);/定義Derived類(lèi)對(duì)象dd.var0 = 2;/直接訪(fǎng)問(wèn)虛基類(lèi)的數(shù)據(jù)成員d.fun0();/直接訪(fǎng)問(wèn)虛基類(lèi)的函數(shù)成員return 0;7.5 派生類(lèi)成員的標(biāo)識(shí)與訪(fǎng)問(wèn) 7.5.3 虛基類(lèi)及其派生類(lèi)構(gòu)造函數(shù)7.6 程序?qū)嵗酶咚瓜シń饩€(xiàn)性方程組617.6 程序?qū)嵗酶咚瓜シń饩€(xiàn)性方程組算法原理求解Ax = b經(jīng)過(guò)推算得到計(jì)算公式:627

42、.6.1 算法基本原理 7.6.2 程序設(shè)計(jì)分析637.6 程序?qū)嵗酶咚瓜シń饩€(xiàn)性方程組LinearEqu- sums : double *- solution : double *+ LinearEqu(dims : int = 2)+ LinearEqu()+ setLinearEqu(a : const double*, b : double *) : void + printLinearEqu () : void+ solve() : bool + printSolution() : voidMatrix- size : int- elements : double*+ Matri

43、x(size : int = 2)+ Matrix()+ setMatrix(values : const double*) : void + printMatrix() : void + getSize() : int+ element(i : int, j : int) : double & + element(i : int, j : int) : double7.6.3 源程序及說(shuō)明例7-9 全選主元高斯消去法解線(xiàn)性方程組整個(gè)程序分為三個(gè)獨(dú)立的文檔,LinearEqu.h文件中包括矩陣類(lèi)Matrix和線(xiàn)性方程組類(lèi)LinearEqu的定義,LinearEqu.cpp文件中包括這兩個(gè)類(lèi)的成

44、員函數(shù)實(shí)現(xiàn)文件;lequmain.cpp文件包括程序的主函數(shù),主函數(shù)中定義了一個(gè)類(lèi)LinearEqu的對(duì)象,通過(guò)這個(gè)對(duì)象求解一個(gè)四元線(xiàn)性方程組。647.6 程序?qū)嵗酶咚瓜シń饩€(xiàn)性方程組7.6.3 源程序及說(shuō)明/Matrix.h 文件一,Matrix類(lèi)定義#ifndef _MATRIX_H#define _MATRIX_Hclass Matrix /基類(lèi)Matrix定義public:/外部接口Matrix(int size = 2);/構(gòu)造函數(shù)Matrix();/析構(gòu)函數(shù)void setMatrix(const double *values);/矩陣賦初值void printMatrix()

45、 const;/顯示矩陣int getSize() const return size; /得到矩陣大小double &element(int i, int j) return elementsi * size + j; double element(int i, int j) const return elementsi * size + j; private:/保護(hù)數(shù)據(jù)成員int size;/矩陣的大小double *elements;/矩陣存放數(shù)組首地址;#endif /_MATRIX_H65例7-9(續(xù))7.6 程序?qū)嵗酶咚瓜シń饩€(xiàn)性方程組7.6.3 源程序及說(shuō)明/LinearEq

46、u.h 文件二,LinearEqu類(lèi)定義#ifndef _LINEAR_EQU_H#define _LINEAR_EQU_H#include Matrix.hclass LinearEqu: public Matrix /公有派生類(lèi)LinearEqu定義public:/外部接口LinearEqu(int size = 2);/構(gòu)造函數(shù)LinearEqu();/析構(gòu)函數(shù)/方程賦值void setLinearEqu(const double *a, const double *b);bool solve();/全選主元高斯消去法求解方程void printLinearEqu() const;/顯示

47、方程void printSolution() const;/顯示方程的解private:/私有數(shù)據(jù)double *sums;/方程右端項(xiàng)double *solution;/方程的解;#endif /_LINEAREQU_H66例7-9(續(xù))7.6 程序?qū)嵗酶咚瓜シń饩€(xiàn)性方程組7.6.3 源程序及說(shuō)明/Matrix.cpp 文件三,Matrix類(lèi)實(shí)現(xiàn)#include Matrix.h/包含類(lèi)的定義頭文件#include using namespace std;void Matrix:setMatrix(const double *values) /設(shè)置矩陣for (int i = 0; i

48、size * size; i+)elementsi = valuesi;/矩陣成員賦初值 /矩陣Matrix類(lèi)的構(gòu)造函數(shù)Matrix:Matrix(int size/* = 2 */) : size(size) elements = new doublesize * size;/動(dòng)態(tài)內(nèi)存分配Matrix:Matrix() /矩陣Matrix類(lèi)的析構(gòu)函數(shù)delete elements;/內(nèi)存釋放void Matrix:printMatrix() const /顯示矩陣的元素cout The Matrix is: endl;for(int i = 0; i size; i+) for(int j

49、= 0; j size; j+)cout element(i, j) ;cout endl;67例7-9(續(xù))7.6 程序?qū)嵗酶咚瓜シń饩€(xiàn)性方程組7.6.3 源程序及說(shuō)明/LinearEqu.cpp 文件四,LinearEqu類(lèi)實(shí)現(xiàn)#include LinearEqu.h/包含類(lèi)的定義頭文件#include #include using namespace std;LinearEqu:LinearEqu(int size/* = 2 */) : Matrix(size) /用size調(diào)用基類(lèi)構(gòu)造函數(shù)sums = new doublesize;/動(dòng)態(tài)內(nèi)存分配solution = new do

50、ublesize;LinearEqu:LinearEqu() /派生類(lèi)LinearEqu的析構(gòu)函數(shù)delete sums;/釋放內(nèi)存delete solution;/會(huì)自動(dòng)調(diào)用基類(lèi)析構(gòu)函數(shù)void LinearEqu:setLinearEqu(const double *a, const double *b) /設(shè)置線(xiàn)性方程組setMatrix(a);/調(diào)用基類(lèi)函數(shù)for(int i = 0; i getSize(); i+)sumsi = bi;68例7-9(續(xù))7.6 程序?qū)嵗酶咚瓜シń饩€(xiàn)性方程組7.6.3 源程序及說(shuō)明void LinearEqu:printLinearEqu() c

51、onst /顯示線(xiàn)性方程組cout The Line eqution is: endl;for (int i = 0; i getSize(); i+) for (int j = 0; j getSize(); j+)cout element(i, j) ;cout sumsi endl;void LinearEqu:printSolution() const /輸出方程的解cout The Result is: endl;for (int i = 0; i getSize(); i+)cout x i = solutioni endl;inline void swap(double &v1,

52、 double &v2) /交換兩個(gè)實(shí)數(shù)double temp = v1;v1 = v2;v2 = temp;69例7-9(續(xù))7.6 程序?qū)嵗酶咚瓜シń饩€(xiàn)性方程組7.6.3 源程序及說(shuō)明bool LinearEqu:solve() /全選主元素高斯消去法求解方程int *js=new intgetSize();/存儲(chǔ)主元素所在列號(hào)的數(shù)組for (int k = 0; k getSize() - 1; k+)/選主元素int is;/主元素所在行號(hào)double max = 0;/所有元素的最大值for (int i = k; i getSize(); i+)for (int j = k;

53、j max) max = t;jsk = j;is = i;if (max = 0) delete js;return false;70例7-9(續(xù))7.6 程序?qū)嵗酶咚瓜シń饩€(xiàn)性方程組7.6.3 源程序及說(shuō)明else /通過(guò)行、列交換,把主元素交換到第k行第k列if (jsk != k)for (int i = 0; i getSize(); i+) swap(element(i, k), element(i, jsk);if (is != k) for (int j = k; j getSize(); j+) swap(element(k, j), element(is, j);swa

54、p(sumsk, sumsis);/消去過(guò)程double major = element(k, k);for (int j = k + 1; j getSize(); j+)element(k, j) /= major;sumsk /= major;for (int i = k + 1; i getSize(); i+) for (int j = k + 1; j getSize(); j+) element(i, j) -= element(i, k) * element(k, j);sumsi -= element(i, k) * sumsk;71例7-9(續(xù))7.6 程序?qū)嵗酶咚瓜シ?/p>

55、解線(xiàn)性方程組7.6.3 源程序及說(shuō)明/判斷剩下的一個(gè)元素是否等于0double d = element(getSize() - 1, getSize() - 1);if (fabs(d) = 0; i-) double t = 0.0;for (int j = i + 1; j = 0; k-)if (jsk != k) swap(solutionk, solutionjsk);delete js;return true;72例7-9(續(xù))7.6 程序?qū)嵗酶咚瓜シń饩€(xiàn)性方程組7.6.3 源程序及說(shuō)明/7_9.cpp 文件五,主函數(shù)#include LinearEqu.h/類(lèi)定義頭文件#in

56、clude using namespace std;int main() /主函數(shù)double a= /方程系數(shù)矩陣0.2368, 0.2471, 0.2568, 1.2671,/第一行0.1968, 0.2071, 1.2168, 0.2271,/第二行0.1581, 1.1675, 0.1768, 0.1871,/第三行1.1161, 0.1254, 0.1397, 0.1490 ;/第四行double b = 1.8471, 1.7471, 1.6471, 1.5471 ;/方程右端項(xiàng)LinearEqu equ(4);/定義一個(gè)四元方程組對(duì)象equ.setLinearEqu(a,b);/

57、設(shè)置方程組equ.printLinearEqu();/輸出方程組if (equ.solve()/求解方程組equ.printSolution();/輸出方程組的解elsecoutFailendl;return 0;73例7-9(續(xù))7.6 程序?qū)嵗酶咚瓜シń饩€(xiàn)性方程組7.6.3 源程序及說(shuō)明例7-9(續(xù))運(yùn)行結(jié)果為:The Line eqution is:/方程組0.2368 0.2471 0.2568 1.2671 1.84710.1968 0.2071 1.2168 0.2271 1.74710.1581 1.1675 0.1768 0.1871 1.64711.1161 0.1254

58、 0.1397 0.149 1.5471The Result is:/方程組的解X0=1.04058X1=0.987051X2=0.93504X3=0.881282747.6 程序?qū)嵗酶咚瓜シń饩€(xiàn)性方程組7.6.3 源程序及說(shuō)明7.7.1 問(wèn)題的提出使用繼承和派生往個(gè)人銀行賬戶(hù)管理程序中增加信用賬號(hào)平時(shí)沒(méi)有利息,透支時(shí)需要支付透支利息,且每個(gè)月結(jié)算一次757.7綜合實(shí)例個(gè)人銀行賬戶(hù)管理程序767.7綜合實(shí)例個(gè)人銀行賬戶(hù)管理程序 7.7.2 類(lèi)設(shè)計(jì)-acc : Accumulator-rate : doubleSavingsAccount+SavingsAccount(date : Date

59、, id : int, rate : double) +getRate() : double+deposit(date : Date, amount : double, desc : string)+withdraw(date : Date, amount : double, desc : string)+settle(date : Date)11-acc : Accumulator-credit : double-rate : double-fee : doubleCreditAccount -getDebt() : double+CreditAccount(date : Date, id

60、: int, credit : double, rate : double, fee : double) +getCredit() : double +getRate() : double +getFee() : double +getAvailableCredit() : double+deposit(date : Date, amount : double, desc : string)+withdraw(date : Date, amount : double, desc : string)+settle(date : Date) +show()-year : int-month : i

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論