




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、面向?qū)ο蟪绦蛟O(shè)計(jì)(二)呂俊白第八章對(duì)象生滅第八章對(duì)象生滅n主要內(nèi)容:主要內(nèi)容: 定義構(gòu)造函數(shù);定義構(gòu)造函數(shù); 構(gòu)造函數(shù)的運(yùn)行機(jī)制;構(gòu)造函數(shù)的運(yùn)行機(jī)制; 定義析構(gòu)函數(shù);定義析構(gòu)函數(shù); 析構(gòu)函數(shù)的運(yùn)行機(jī)制;析構(gòu)函數(shù)的運(yùn)行機(jī)制;n重點(diǎn):重點(diǎn):構(gòu)造函數(shù)、析構(gòu)函數(shù)。構(gòu)造函數(shù)、析構(gòu)函數(shù)。概述概述nC+的構(gòu)造函數(shù)和析構(gòu)函數(shù)是類的的構(gòu)造函數(shù)和析構(gòu)函數(shù)是類的特殊特殊成員成員函數(shù),是為了保證類的封裝特性而設(shè)置的。在函數(shù),是為了保證類的封裝特性而設(shè)置的。在程序設(shè)計(jì)中通過定義構(gòu)造函數(shù)和析構(gòu)函數(shù)能夠程序設(shè)計(jì)中通過定義構(gòu)造函數(shù)和析構(gòu)函數(shù)能夠輕松靈活地創(chuàng)建和撤消類對(duì)象。輕松靈活地創(chuàng)建和撤消類對(duì)象。當(dāng)對(duì)象被建立時(shí),構(gòu)造函數(shù)馬
2、上被調(diào)用,自動(dòng)當(dāng)對(duì)象被建立時(shí),構(gòu)造函數(shù)馬上被調(diào)用,自動(dòng)地給對(duì)象分配空間并進(jìn)行初始化;地給對(duì)象分配空間并進(jìn)行初始化;當(dāng)對(duì)象生命期結(jié)束(撤消)時(shí),析構(gòu)函數(shù)由系當(dāng)對(duì)象生命期結(jié)束(撤消)時(shí),析構(gòu)函數(shù)由系統(tǒng)自動(dòng)調(diào)用,釋放對(duì)象所占有的資源。統(tǒng)自動(dòng)調(diào)用,釋放對(duì)象所占有的資源。構(gòu)造函數(shù)和析構(gòu)函數(shù)完善了構(gòu)造函數(shù)和析構(gòu)函數(shù)完善了C+的類機(jī)制。的類機(jī)制。8.1 構(gòu)造函數(shù)構(gòu)造函數(shù)1為什么要引入構(gòu)造函數(shù)為什么要引入構(gòu)造函數(shù)n面向?qū)ο蠓椒ㄖ械念愂且唤M具有相同屬性和行面向?qū)ο蠓椒ㄖ械念愂且唤M具有相同屬性和行為的對(duì)象的抽象。為的對(duì)象的抽象。類描述的是一組事物所具有的共同性質(zhì)。類描述的是一組事物所具有的共同性質(zhì)。對(duì)象是類的實(shí)例
3、,是確實(shí)存在的實(shí)體,它具有對(duì)象是類的實(shí)例,是確實(shí)存在的實(shí)體,它具有確定的屬性。確定的屬性。由于對(duì)象的意義表達(dá)了現(xiàn)實(shí)世界的實(shí)體,它具有由于對(duì)象的意義表達(dá)了現(xiàn)實(shí)世界的實(shí)體,它具有確定的屬性,因此,一旦建立對(duì)象,就必須要確定的屬性,因此,一旦建立對(duì)象,就必須要有一個(gè)有意義的初始值。有一個(gè)有意義的初始值。2. 定義構(gòu)造函數(shù)定義構(gòu)造函數(shù)由于對(duì)象的一部分屬性(即類的一部分?jǐn)?shù)據(jù)成員)由于對(duì)象的一部分屬性(即類的一部分?jǐn)?shù)據(jù)成員)是私有的是私有的(private)(private)、被保護(hù)的、被保護(hù)的(protected)(protected),只允許類的成員函數(shù)來訪問它,所以,對(duì)象的只允許類的成員函數(shù)來訪問它
4、,所以,對(duì)象的初始化任務(wù),必須由類的成員函數(shù)來完成。構(gòu)初始化任務(wù),必須由類的成員函數(shù)來完成。構(gòu)造函數(shù)就是這樣一個(gè)特殊的成員函數(shù)。造函數(shù)就是這樣一個(gè)特殊的成員函數(shù)。 (1)構(gòu)造函數(shù)的命名構(gòu)造函數(shù)的命名構(gòu)造函數(shù)名必須與類名相同。構(gòu)造函數(shù)名必須與類名相同。 (2)定義構(gòu)造函數(shù)定義構(gòu)造函數(shù)我們可以象定義其它成員函數(shù)一樣定義構(gòu)造函數(shù)。我們可以象定義其它成員函數(shù)一樣定義構(gòu)造函數(shù)。即:即:構(gòu)造函數(shù)可以在類的內(nèi)部定義,也可以在構(gòu)造函數(shù)可以在類的內(nèi)部定義,也可以在類的外部定義。類的外部定義。例如:例如:(P:297)定義一個(gè)平面坐標(biāo)類定義一個(gè)平面坐標(biāo)類Ppoint,使用該類以計(jì)算坐標(biāo)點(diǎn)的直,使用該類以計(jì)算坐標(biāo)點(diǎn)
5、的直角坐標(biāo)所對(duì)應(yīng)的極坐標(biāo)。(角坐標(biāo)所對(duì)應(yīng)的極坐標(biāo)。(使用了頭文件衛(wèi)士使用了頭文件衛(wèi)士P:246)/ ppoint.h#ifndef HEADER_PPOINT#define HEADER_PPOINTclass PPoint double x, y; /直角坐標(biāo)直角坐標(biāo)public: PPoint(double ix, double iy); / 構(gòu)造函數(shù)聲明構(gòu)造函數(shù)聲明:設(shè)置坐標(biāo)設(shè)置坐標(biāo) double xOffset(); /直角坐標(biāo)直角坐標(biāo)x分量分量 double yOffset(); /直角坐標(biāo)直角坐標(biāo)y分量分量 double angle(); /極坐標(biāo)弧角極坐標(biāo)弧角 double ra
6、dius(); /極坐標(biāo)半徑極坐標(biāo)半徑;/=#endif / HEADER_PPOINT / ppoint.cpp#includeppoint.h#includePPoint:PPoint(double ix, double iy) /構(gòu)造函數(shù)定義構(gòu)造函數(shù)定義 x=ix; y=iy; double PPoint:xOffset() return x;double PPoint:yOffset() return y;double PPoint:angle() return (180/3.14159)*atan2(y,x);double PPoint:radius() return sqrt(x*
7、x+y*y); / f0902.cpp using PPoint#includeppoint.h#includeusing namespace std;int main() for(double x,y; coutxy & x=0; ) PPoint p(x,y); coutangle=p.angle(), radius=p.radius(), x offset= p.xOffset(), y offset=p.yOffset()n; return 1;/= 注意:注意:1)C+規(guī)定:構(gòu)造函數(shù)名必須與類名相同,規(guī)定:構(gòu)造函數(shù)名必須與類名相同,它在該類對(duì)象創(chuàng)建時(shí)自動(dòng)被調(diào)用。它在該類對(duì)象創(chuàng)
8、建時(shí)自動(dòng)被調(diào)用。2)構(gòu)造函數(shù)無返回類型。構(gòu)造函數(shù)無返回類型。構(gòu)造函數(shù)沒有返回類型,函數(shù)體中也不允構(gòu)造函數(shù)沒有返回類型,函數(shù)體中也不允許包含返回值語句,但可以有無值返回許包含返回值語句,但可以有無值返回語句語句“return;”。例如:例如:class Person public: int Person() /return 1;/;錯(cuò)誤:錯(cuò)誤:1、構(gòu)造函數(shù)是無返回類型的;、構(gòu)造函數(shù)是無返回類型的; 2、構(gòu)造函數(shù)體內(nèi)只能使用無值返回語句、構(gòu)造函數(shù)體內(nèi)只能使用無值返回語句class Personpublic:Person()/正確正確 / return;/正確正確/;注意:注意:3)在類外部定義的構(gòu)
9、造函數(shù),其函數(shù)名前要加上在類外部定義的構(gòu)造函數(shù),其函數(shù)名前要加上“類名類名:”。4)直接以類名(構(gòu)造函數(shù)名)調(diào)用構(gòu)造函數(shù),則直接以類名(構(gòu)造函數(shù)名)調(diào)用構(gòu)造函數(shù),則產(chǎn)生一個(gè)無名對(duì)象。產(chǎn)生一個(gè)無名對(duì)象。例如:例如:PPoint(3,5);無名對(duì)象一般用在創(chuàng)建后不需要反復(fù)使用的場(chǎng)合,無名對(duì)象一般用在創(chuàng)建后不需要反復(fù)使用的場(chǎng)合,常在參數(shù)傳遞時(shí)用到。常在參數(shù)傳遞時(shí)用到。8.2構(gòu)造函數(shù)的重載構(gòu)造函數(shù)的重載/ f0903.cpp 構(gòu)造函數(shù)重載構(gòu)造函數(shù)重載#include#includeusing namespace std;class Date int year, month, day;public: D
10、ate(int y=2000, int m=1, int d=1); / 設(shè)置默認(rèn)參數(shù)設(shè)置默認(rèn)參數(shù) Date(const string& s); / 重載重載 bool isLeapYear()const; void print();8.2.1重載構(gòu)造函數(shù)重載構(gòu)造函數(shù)n構(gòu)造函數(shù)不但可以重載,還可以設(shè)置默認(rèn)參數(shù)。構(gòu)造函數(shù)不但可以重載,還可以設(shè)置默認(rèn)參數(shù)。例如:例如: (P:299)Date:Date(const string& s) year = atoi(s.substr(0,4).c_str();/如:如: 2008-05-12 month = atoi(s.substr(5
11、,2).c_str(); day = atoi(s.substr(8,2).c_str();/-Date:Date(int y, int m, int d) year=y,month=m,day=d; bool Date:isLeapYear()const return (year % 4=0 & year % 100 )| year % 400=0;void Date:print() coutsetfill(0)setw(4)year-setw(2) month-setw(2)daynsetfill( );int main() Date c(2005-12-28); Date d(2
12、003,12,6); Date e(2002); / 默認(rèn)兩個(gè)參數(shù)默認(rèn)兩個(gè)參數(shù) Date f(2002,12); / 默認(rèn)一個(gè)參數(shù)默認(rèn)一個(gè)參數(shù) Date g; / 默認(rèn)三個(gè)參數(shù)默認(rèn)三個(gè)參數(shù) c.print ();d.print ();e.print ();f.print ();g.print (); return 1;/=當(dāng)處理過程不同時(shí),使用當(dāng)處理過程不同時(shí),使用重載;當(dāng)處理過程類似時(shí),重載;當(dāng)處理過程類似時(shí),用默認(rèn)參數(shù)可以省去一些用默認(rèn)參數(shù)可以省去一些重復(fù)的編碼工作。重復(fù)的編碼工作。8.2.2無參數(shù)構(gòu)造函數(shù)無參數(shù)構(gòu)造函數(shù)n無參構(gòu)造函數(shù)也稱默認(rèn)構(gòu)造函數(shù),系統(tǒng)默認(rèn),類類型無參構(gòu)造函數(shù)也稱默認(rèn)構(gòu)
13、造函數(shù),系統(tǒng)默認(rèn),類類型定義中若無構(gòu)造函數(shù),照樣可以用對(duì)象定義語句創(chuàng)建定義中若無構(gòu)造函數(shù),照樣可以用對(duì)象定義語句創(chuàng)建對(duì)象。對(duì)象。即:類機(jī)制中總是為無構(gòu)造函數(shù)的類默認(rèn)地建立一個(gè)無即:類機(jī)制中總是為無構(gòu)造函數(shù)的類默認(rèn)地建立一個(gè)無參的構(gòu)造函數(shù),它除了分配對(duì)象的實(shí)體空間外,其他參的構(gòu)造函數(shù),它除了分配對(duì)象的實(shí)體空間外,其他什么也不做。什么也不做。例如:例如:class Date public: /類定義中無構(gòu)造函數(shù)類定義中無構(gòu)造函數(shù) / 相當(dāng)于定義了相當(dāng)于定義了Date();int main() Date d; / ok / .n注意:注意:如果手工定義了無參構(gòu)造函數(shù),或者任何其如果手工定義了無參構(gòu)造
14、函數(shù),或者任何其他的構(gòu)造函數(shù),則系統(tǒng)不再提供默認(rèn)的無參構(gòu)造函數(shù)。他的構(gòu)造函數(shù),則系統(tǒng)不再提供默認(rèn)的無參構(gòu)造函數(shù)。例例1:class Date public: Date(int y, int m, int d) / .;int main() Date d; / error / .例例2:class A/私有成員私有成員public:A(int x)A(string s)/其他公有成員其他公有成員;/-A a(2);A c;/錯(cuò):錯(cuò):no appropriate default constructor available8.3類成員初始化類成員初始化8.3.1默認(rèn)調(diào)用的無參數(shù)構(gòu)造函數(shù)默認(rèn)調(diào)用的無參
15、數(shù)構(gòu)造函數(shù)n類定義中有數(shù)據(jù)成員和成員函數(shù),數(shù)據(jù)類定義中有數(shù)據(jù)成員和成員函數(shù),數(shù)據(jù)成員可以是內(nèi)部數(shù)據(jù)類型的變量實(shí)體,成員可以是內(nèi)部數(shù)據(jù)類型的變量實(shí)體,也可以是對(duì)象實(shí)體。也可以是對(duì)象實(shí)體。例如:有一個(gè)學(xué)號(hào)類和一個(gè)學(xué)生類,學(xué)生類中包例如:有一個(gè)學(xué)號(hào)類和一個(gè)學(xué)生類,學(xué)生類中包含了學(xué)號(hào)類的對(duì)象,這樣在構(gòu)造學(xué)生類對(duì)象時(shí),含了學(xué)號(hào)類的對(duì)象,這樣在構(gòu)造學(xué)生類對(duì)象時(shí),就面臨著學(xué)號(hào)類對(duì)象的構(gòu)造。就面臨著學(xué)號(hào)類對(duì)象的構(gòu)造。/ f0905.cpp 對(duì)象成員的默認(rèn)構(gòu)造對(duì)象成員的默認(rèn)構(gòu)造#include#include using namespace std;class StudentID/學(xué)號(hào)類學(xué)號(hào)類 int valu
16、e;public: StudentID( )/無參數(shù)構(gòu)造函數(shù)無參數(shù)構(gòu)造函數(shù) static int nextStudentID = 0; /靜態(tài)局部變量靜態(tài)局部變量 value = +nextStudentID; coutAssigning student id valuen; ;/-class Student/學(xué)生類學(xué)生類 string name; StudentID id;/對(duì)象成員對(duì)象成員public: Student(string n = noName) cout Constructing student + n + n; name = n; ;/-int main() Student
17、s(Randy); return 1;/=nC+的類機(jī)制對(duì)于含有對(duì)象成員的類對(duì)象的的類機(jī)制對(duì)于含有對(duì)象成員的類對(duì)象的構(gòu)造制定了一些規(guī)則,其內(nèi)部的執(zhí)行次序如下:構(gòu)造制定了一些規(guī)則,其內(nèi)部的執(zhí)行次序如下:(1)分配對(duì)象空間;分配對(duì)象空間;(2)根據(jù)在類中聲明的根據(jù)在類中聲明的對(duì)象成員對(duì)象成員的次序依次調(diào)用的次序依次調(diào)用其構(gòu)造函數(shù);其構(gòu)造函數(shù);(3)執(zhí)行自己的構(gòu)造函數(shù)。執(zhí)行自己的構(gòu)造函數(shù)。8.3.2 成員的初始化成員的初始化n若要調(diào)用對(duì)象成員的有參構(gòu)造函數(shù),須顯式調(diào)用。其方若要調(diào)用對(duì)象成員的有參構(gòu)造函數(shù),須顯式調(diào)用。其方法為:法為:在構(gòu)造函數(shù)的參數(shù)列表右括號(hào)后面,花括號(hào)前面,在構(gòu)造函數(shù)的參數(shù)列表右括
18、號(hào)后面,花括號(hào)前面,用冒號(hào)引出構(gòu)造函數(shù)的調(diào)用表。用冒號(hào)引出構(gòu)造函數(shù)的調(diào)用表。例如:例如:/ f0907.cpp initialization of class members#include#include using namespace std;class StudentID int value;public: StudentID(int id=0) value=id; cout Assigning student id value endl; ;/-class Student string name; StudentID id;public: Student(string n=no nam
19、e, int ssID=0):id(ssID),name(n) coutConstructing student nn; ;/-int main() Student s(Randy, 98); Student t(Jenny); return 1;相當(dāng)于:相當(dāng)于:StudentID id(ssID);n對(duì)于常量成員和引用成員的初始化也可用構(gòu)造對(duì)于常量成員和引用成員的初始化也可用構(gòu)造參數(shù)表的方式解決。例如:參數(shù)表的方式解決。例如:P306.cpp#include using namespace std;class Silly const int ten;int &ra;public:Si
20、lly(int x,int &a):ten(x),ra(a)void print()coutten=ten,ra=raendl;int main() int a=20; Silly sy(10,a); sy.print(); return 1;小結(jié):小結(jié):n對(duì)于變量成員有兩種初始化方式:對(duì)于變量成員有兩種初始化方式:例如:例如:class Date int year, month, day;public: Date(int y=2000, int m=1, int d=1); / 設(shè)置默認(rèn)參數(shù)設(shè)置默認(rèn)參數(shù) /;1.Date:Date(int y,int m,int d)year=y,m
21、onth=m,day=d;2.Date:Date(int y,int m,int d):year(y),month(m),day(d)8.4構(gòu)造順序構(gòu)造順序nC+給構(gòu)造對(duì)象的順序做了專門的規(guī)定:給構(gòu)造對(duì)象的順序做了專門的規(guī)定:局部對(duì)象局部對(duì)象v局部對(duì)象和靜態(tài)局部對(duì)象構(gòu)造的順序與它們?cè)诔叹植繉?duì)象和靜態(tài)局部對(duì)象構(gòu)造的順序與它們?cè)诔绦蛑谐霈F(xiàn)的順序是一致的。序中出現(xiàn)的順序是一致的。C+是根據(jù)運(yùn)行中是根據(jù)運(yùn)行中定義對(duì)象的順序來決定對(duì)象的創(chuàng)建順序,而且,定義對(duì)象的順序來決定對(duì)象的創(chuàng)建順序,而且,靜態(tài)局部對(duì)象只創(chuàng)建一次。靜態(tài)局部對(duì)象只創(chuàng)建一次。例如:例如:/ f0908.cpp/ test local ob
22、ject create order#includeusing namespace std;class Apublic: A() cout; ;/-class Bpublic: B() cout; ;/-class Cpublic: C() cout; ;/-void func() coutnfunc: ; A a; static B b; /靜態(tài)局部對(duì)象靜態(tài)局部對(duì)象 C c;/-int main() coutmain: ; for(int i=1; i=2; +i) for(int j=1; j=2; +j) if(i=2) C c; else A a; B b; func(); func()
23、; return 1;全局對(duì)象全局對(duì)象n和全局變量一樣,所有全局對(duì)象在主函數(shù)和全局變量一樣,所有全局對(duì)象在主函數(shù)(main)啟動(dòng)之前全部已被構(gòu)造。啟動(dòng)之前全部已被構(gòu)造。n全局對(duì)象的調(diào)試方法:全局對(duì)象的調(diào)試方法:(1)將全局對(duì)象先作為局部對(duì)象來調(diào)試;將全局對(duì)象先作為局部對(duì)象來調(diào)試;(2)在所有懷疑有錯(cuò)的構(gòu)造函數(shù)的開頭增加輸出在所有懷疑有錯(cuò)的構(gòu)造函數(shù)的開頭增加輸出語句語句n全局對(duì)象沒有明確的控制流來表明其構(gòu)造順序。全局對(duì)象沒有明確的控制流來表明其構(gòu)造順序。n全局對(duì)象的創(chuàng)建順序在標(biāo)準(zhǔn)全局對(duì)象的創(chuàng)建順序在標(biāo)準(zhǔn)C+中沒有規(guī)定,中沒有規(guī)定,一切視編譯器的內(nèi)在特性而定。一切視編譯器的內(nèi)在特性而定。例如:例如
24、:/ student.h#includeusing namespace std;class Student const int id;public: Student(int d):id(d) coutstudentn; void print() coutidn; ;/-class Tutor Student s;public: Tutor(Student& st):s(st) couttutorn; s.print(); ;/-/ f0909.cpp test global object create order#includestudent.hextern Student ra;/-
25、Tutor je(ra); /全局對(duì)象全局對(duì)象int main()return 1; / f09092.cpp test global object create order#includestudent.hStudent ra(18); /全局對(duì)象全局對(duì)象注意:注意:為了避免編譯器實(shí)現(xiàn)中的不確定問題,應(yīng)盡為了避免編譯器實(shí)現(xiàn)中的不確定問題,應(yīng)盡量不要設(shè)置全局對(duì)象,更不要讓全局對(duì)象之間互相量不要設(shè)置全局對(duì)象,更不要讓全局對(duì)象之間互相依賴。依賴。成員對(duì)象成員對(duì)象n成員對(duì)象以其在類中聲明的順序構(gòu)造。成員對(duì)象以其在類中聲明的順序構(gòu)造。例如:例如:/ f0910.cpp test member obje
26、ct create order#includeusing namespace std;class Apublic: A(int x) coutA:x; ;/-class Bpublic: B(int x) coutB:x; ;/-class C A a; B b;public: C(int x,int y):b(x),a(y) coutCn; ;/-int main() C c(15, 9); return 1;構(gòu)造位置構(gòu)造位置n全局對(duì)象、常對(duì)象、靜態(tài)對(duì)象都放在全全局對(duì)象、常對(duì)象、靜態(tài)對(duì)象都放在全局?jǐn)?shù)據(jù)區(qū);局?jǐn)?shù)據(jù)區(qū);n在函數(shù)中定義的局部對(duì)象,放在棧區(qū);在函數(shù)中定義的局部對(duì)象,放在棧區(qū);n用用n
27、ew申請(qǐng)的空間都在動(dòng)態(tài)內(nèi)存區(qū)(即申請(qǐng)的空間都在動(dòng)態(tài)內(nèi)存區(qū)(即堆區(qū))。堆區(qū))。8.5拷貝構(gòu)造函數(shù)拷貝構(gòu)造函數(shù) (P:315)n拷貝構(gòu)造函數(shù)是一種拷貝構(gòu)造函數(shù)是一種特殊特殊的構(gòu)造函數(shù),具有一的構(gòu)造函數(shù),具有一般構(gòu)造函數(shù)的所有特性。般構(gòu)造函數(shù)的所有特性。n拷貝構(gòu)造函數(shù)的拷貝構(gòu)造函數(shù)的形參是本類對(duì)象的引用形參是本類對(duì)象的引用。n拷貝構(gòu)造函數(shù)的作用是:使用一個(gè)已經(jīng)存在的拷貝構(gòu)造函數(shù)的作用是:使用一個(gè)已經(jīng)存在的對(duì)象(由拷貝構(gòu)造函數(shù)的參數(shù)指定的對(duì)象),對(duì)象(由拷貝構(gòu)造函數(shù)的參數(shù)指定的對(duì)象),去初始化一個(gè)新的去初始化一個(gè)新的同類對(duì)象同類對(duì)象。用戶可以根據(jù)自己實(shí)際問題的需要定義特定的拷用戶可以根據(jù)自己實(shí)際問題的
28、需要定義特定的拷貝構(gòu)造函數(shù),以實(shí)現(xiàn)同類對(duì)象之間數(shù)據(jù)成員的貝構(gòu)造函數(shù),以實(shí)現(xiàn)同類對(duì)象之間數(shù)據(jù)成員的傳遞。傳遞。定義拷貝構(gòu)造函數(shù)的一般形式為:定義拷貝構(gòu)造函數(shù)的一般形式為:class 類名類名 public: 類名(形參表);類名(形參表);/構(gòu)造函數(shù)構(gòu)造函數(shù) 類名(類名類名(類名 對(duì)象名);對(duì)象名); /拷貝構(gòu)造函數(shù)拷貝構(gòu)造函數(shù) ;類名類名:類名(類名類名(類名 對(duì)象名)對(duì)象名)/拷貝構(gòu)造函數(shù)的實(shí)現(xiàn)拷貝構(gòu)造函數(shù)的實(shí)現(xiàn)函數(shù)體函數(shù)體 另一常見的形式另一常見的形式: class 類名類名 public: 類名(形參表);類名(形參表);/構(gòu)造函數(shù)構(gòu)造函數(shù) 類名(類名(const 類名類名 對(duì)象名);對(duì)
29、象名); /拷貝構(gòu)造函數(shù)拷貝構(gòu)造函數(shù) ; 類名類名:類名(類名(const類名類名 對(duì)象名)對(duì)象名)/拷貝構(gòu)造函數(shù)的實(shí)現(xiàn)拷貝構(gòu)造函數(shù)的實(shí)現(xiàn)函數(shù)體函數(shù)體 用用const限定引用的目的是限定引用的目的是:為了確保參數(shù)對(duì)象的所有數(shù)據(jù)成為了確保參數(shù)對(duì)象的所有數(shù)據(jù)成員值在拷貝構(gòu)造函數(shù)體內(nèi)不會(huì)被改變。員值在拷貝構(gòu)造函數(shù)體內(nèi)不會(huì)被改變。#include using namespace std;class Point public:Point (int xx=0,int yy =0);Point(const Point &p);/聲明拷貝構(gòu)造函數(shù)聲明拷貝構(gòu)造函數(shù)int GetX( ) return X
30、;int GetY( ) return Y;private: int X,Y;Point:Point (int xx,int yy)X=xx;Y=yy;cout構(gòu)造函數(shù)被調(diào)用構(gòu)造函數(shù)被調(diào)用endl;Point:Point(const Point &p)/拷貝構(gòu)造函數(shù)的實(shí)現(xiàn)拷貝構(gòu)造函數(shù)的實(shí)現(xiàn)X=p.X;Y=p.Y;cout拷貝構(gòu)造函數(shù)被調(diào)用拷貝構(gòu)造函數(shù)被調(diào)用endl;例如:例如:Copy_Constructor.cpp注意:注意:普通構(gòu)造函數(shù)是在對(duì)象創(chuàng)建時(shí)被調(diào)用,而普通構(gòu)造函數(shù)是在對(duì)象創(chuàng)建時(shí)被調(diào)用,而拷貝構(gòu)拷貝構(gòu)造函數(shù)在以下三種情況下都會(huì)被調(diào)用:造函數(shù)在以下三種情況下都會(huì)被調(diào)用:(1)當(dāng)
31、用類的一個(gè)對(duì)象去初始化該類的另一個(gè)對(duì)當(dāng)用類的一個(gè)對(duì)象去初始化該類的另一個(gè)對(duì)象時(shí)。象時(shí)。int main( )Point A(1,2);Point B(A);cout對(duì)象對(duì)象B的的X坐標(biāo):坐標(biāo):B.GetX()endl;return 1;(2)如果如果函數(shù)的形參是類的對(duì)象函數(shù)的形參是類的對(duì)象,調(diào)用函數(shù),進(jìn),調(diào)用函數(shù),進(jìn)行形參和實(shí)參結(jié)合時(shí)。行形參和實(shí)參結(jié)合時(shí)。void f(Point p)coutp.GetX()endl;int main()Point A(1,2);f(A);return 1;(3)如果如果函數(shù)的返回值是類的對(duì)象函數(shù)的返回值是類的對(duì)象,函數(shù)調(diào)用完,函數(shù)調(diào)用完成返回時(shí)。成返回時(shí)。P
32、oint g() Point A(1,2);return A;int main()Point B;coutCalling g.endl;B=g();return 1;n如果程序員沒有為類聲明拷貝構(gòu)造函數(shù),則編如果程序員沒有為類聲明拷貝構(gòu)造函數(shù),則編譯器自己生成一個(gè)拷貝構(gòu)造函數(shù)。譯器自己生成一個(gè)拷貝構(gòu)造函數(shù)。n該構(gòu)造函數(shù)的功能是:該構(gòu)造函數(shù)的功能是:把參數(shù)對(duì)象的每個(gè)數(shù)據(jù)把參數(shù)對(duì)象的每個(gè)數(shù)據(jù)成員的值都復(fù)制到新建立的對(duì)象中。成員的值都復(fù)制到新建立的對(duì)象中。例如:例如:/ f0912_modi.cpp constructing object from other object#includeusing
33、 namespace std;class Person char* pName;/P:315圖圖9-3public: Person(char* pN=noName) coutConstructing pNn; pName = new charstrlen(pN)+1; if(pName) strcpy(pName,pN); void print() coutName:pNameendl;/-int main() Person p1(Randy); Person p2(p1); p2.print(); return 1;修改修改/ f0912_modi.cpp constructing obje
34、ct from other object(新增析構(gòu)函數(shù))(新增析構(gòu)函數(shù))#includeusing namespace std;class Person char* pName;public: Person(char* pN=noName) coutConstructing pNn; pName = new charstrlen(pN)+1; if(pName) strcpy(pName,pN); void print() coutName:pNameendl;Person()/析構(gòu)函數(shù)析構(gòu)函數(shù) cout Destructing pNamen; delete pName; ;/-int mai
35、n() Person p1(Randy); Person p2(p1); p2.print(); return 1;原因:析構(gòu)原因:析構(gòu)p2時(shí)將存有時(shí)將存有Randy的空間先行釋放了,輪到析的空間先行釋放了,輪到析構(gòu)構(gòu)p1時(shí),時(shí),Randy已經(jīng)不復(fù)存在了。已經(jīng)不復(fù)存在了。/ f0913.cpp copy constructor#includeusing namespace std;class Person char* pName;public: Person(char* pN=noName) coutConstructing pNn; pName = new charstrlen(pN)+1; if(pName) strcpy(pName,pN); Person(const Person& s)/拷貝構(gòu)造函數(shù)拷貝構(gòu)造函數(shù) coutcopy Construct
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 三年級(jí)教師線上教學(xué)總結(jié)
- 廠區(qū)電子合同范本
- 勞務(wù)磚體合同范本
- 印刷廣告標(biāo)牌合同范本
- 企業(yè)員工股合同范本
- 《韓愈短文》教案
- 合買別墅合同范本
- 《這片土地是神圣的》說課稿
- 《觀滄?!烽喿x答案及鑒賞
- 任務(wù)目標(biāo)認(rèn)購合同范例
- 學(xué)做小小按摩師(課件)全國通用三年級(jí)上冊(cè)綜合實(shí)踐活動(dòng)
- 陰道鏡檢查臨床醫(yī)學(xué)知識(shí)及操作方法講解培訓(xùn)PPT
- “教學(xué)評(píng)一體化”指導(dǎo)的語文教學(xué)設(shè)計(jì)以統(tǒng)編版語文四年級(jí)上冊(cè)《蟋蟀的住宅》為例
- AI09人工智能-多智能體
- 石墨烯商業(yè)計(jì)劃書
- 放射源基本知識(shí)培訓(xùn)課件
- 【革命歷史題材舞蹈創(chuàng)作手法及思考案例-以紅船為例9400字(論文)】
- 腦血管造影術(shù)后病人的護(hù)理查房
- 美術(shù)高考色彩備考教學(xué)策略
- 2023年云南省新聞系統(tǒng)事業(yè)單位人員招聘筆試題庫及答案解析
- 教學(xué)設(shè)計(jì)心肺復(fù)蘇
評(píng)論
0/150
提交評(píng)論