C程序設(shè)計課件:第12章 構(gòu)造函數(shù)_第1頁
C程序設(shè)計課件:第12章 構(gòu)造函數(shù)_第2頁
C程序設(shè)計課件:第12章 構(gòu)造函數(shù)_第3頁
C程序設(shè)計課件:第12章 構(gòu)造函數(shù)_第4頁
C程序設(shè)計課件:第12章 構(gòu)造函數(shù)_第5頁
已閱讀5頁,還剩46頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、第十二章 構(gòu)造函數(shù)本章主要內(nèi)容12.1 類與對象12.2 構(gòu)造函數(shù)的需要性12.3 構(gòu)造函數(shù)的使用12.4 析構(gòu)函數(shù)12.5 帶參數(shù)的構(gòu)造函數(shù)12.6 重載構(gòu)造函數(shù)12.7 默認(rèn)構(gòu)造函數(shù)12.8 類成員初始化的困惑12.9 構(gòu)造類成員12.10 構(gòu)造對象的順序作業(yè)212.1 類與對象1. 類與對象的區(qū)別類:抽象的對象:具體的,是類的一個具體的實例。對象有屬性和操作對象可以被創(chuàng)建和銷毀,但類是無所不在的。2.對象的定義:在11.4節(jié)中已介紹3.對象的初始化:構(gòu)造、并初始化對象312.2 構(gòu)造函數(shù)的需要性變量初始化的方法如下: int a=1; int * pa=&a;數(shù)組初始化的方法如下: in

2、t b =1,2,3,4;結(jié)構(gòu)初始化的方法如下: struct Student /總需學(xué)時數(shù) int somesHours; float gpa; /平均成績 ; void fn( ) Student s=100, 3.5; /創(chuàng)建結(jié)構(gòu)變量時初始化 / 4由于類的封裝性,類的對象的初始化的任務(wù)只能由類的成員函數(shù)完成:構(gòu)造函數(shù)構(gòu)造函數(shù):在類定義體中,與類同名的成員函數(shù)作用:在創(chuàng)建對象時,由系統(tǒng)自動調(diào)用(在編譯時,由編譯器自動完成),對對象進(jìn)行初始化 12.2 構(gòu)造函數(shù)的需要性5構(gòu)造函數(shù)可以放在類的外部定義,加“類名:”。例: #include class Desk public: Desk( )

3、; /構(gòu)造函數(shù)聲明 protected: int weight; int high; int width; int length; ;12.3 構(gòu)造函數(shù)的使用class Stool public: Stool( ); /構(gòu)造函數(shù)聲明 protected: int weight; int high; int width; int length; ;6Desk:Desk( ) /構(gòu)造函數(shù)定義 weight=10; high=5; width=5; length=5; cout weight high width length endl; Page 7Stool:Stool( ) /構(gòu)造函數(shù)定義 w

4、eight=6; high=3; width=3; length=3; cout weight high width length endl; 12.3 構(gòu)造函數(shù)的使用7 void fn( ) Desk da; /自動調(diào)用Desk( ) Stool sa; /自動調(diào)用Stool( ) int main( ) fn( ); 主函數(shù)運行時調(diào)用fn( ), fn( )在創(chuàng)建Desk對象da和Stool對象sa時,分別調(diào)用了兩者的構(gòu)造函數(shù)。12.3 構(gòu)造函數(shù)的使用8構(gòu)造函數(shù)沒有返回類型,函數(shù)體中不允許返回值,但可以有無值返回語句“return;”。例: void Desk:Desk( ) /error

5、:構(gòu)造函數(shù)定義如果在上例中的函數(shù)fn( )中,定義桌子對象的語句改成定義對象數(shù)組: void fn( ) Desk dd5; /對象數(shù)組dd Stool sa; / 則定義對象數(shù)組的語句構(gòu)造函數(shù)會被調(diào)用5次。Page 912.3 構(gòu)造函數(shù)的使用9類定義中 ,類的數(shù)據(jù)成員可能為另一個類的對象, 此時在類的對象創(chuàng)建所調(diào)用的構(gòu)造函數(shù)中,對該成員(對象)自動調(diào)用其構(gòu)造函數(shù)。例: #include class Student public: Student( ) cout constructing student.n; semesHours=100; gpa=3.5; /其他公共成員 protected

6、: int semesHours; float gpa; ;class Teacher public: Teacher( ) cout constructing teacher.n; ; 12.3 構(gòu)造函數(shù)的使用10class TutorPair public: TutorPair( ) cout constructing tutorpair.n; noMeetings=0; protected: Student student; Teacher teacher; int noMeetings; /會晤次數(shù);int main( ) TutorPair tp; cout back in main

7、.n; Page 11運行結(jié)果為:constructing student.constructing teache.constructing tutorpair.back in main.12.3 構(gòu)造函數(shù)的使用1112.4 析構(gòu)函數(shù)析構(gòu)函數(shù)也是特殊的類成員函數(shù),它沒有返回類型,沒有參數(shù),不能隨意調(diào)用,也沒有重載。析構(gòu)函數(shù):在類定義體中,與類同名、并在前面冠以“”的成員函數(shù) 。作用:釋放對象在構(gòu)造中分配的資源(例如:關(guān)閉被構(gòu)造函數(shù)打開的文件,釋放動態(tài)內(nèi)存)。在對象生命期結(jié)束時,由系統(tǒng)自動調(diào)用,并且以與構(gòu)造函數(shù)相反的調(diào)用順序被調(diào)用。12#include class Student public:

8、 Student( ) cout constructing student.n; semesHours=100; gpa=3.5; Student( )cout destructing student.n; /其他公共成員 protected: int semesHours; float gpa;class Teacher public: Teacher( )cout constructing teacher.n; Teacher( )cout destructing teacher.n; ;13class TutorPair public: TutorPair( ) cout constru

9、cting tutorpair.n; noMeetings=0; TutorPair( )cout destructing tutorpair.n; protected: Student student; Teacher teacher; int noMeetings; ; int main() TutorPair tp; cout back in main.n; 運行結(jié)果: constructing student. constructing teacher. constructing tutorpair. back in main. destructing tutorpair. destr

10、ucting teacher. destructing student. 注意:構(gòu)造函數(shù)和析構(gòu)函數(shù)的調(diào)用順序正好相反。1412.5 帶參數(shù)的構(gòu)造函數(shù)不帶參數(shù)的構(gòu)造函數(shù)對數(shù)據(jù)成員的初始化,取決于構(gòu)造函數(shù)體中對哪些數(shù)據(jù)成員進(jìn)行賦初值,且用此構(gòu)造函數(shù)構(gòu)造的所有對象的初始值都相同。 帶參數(shù)的構(gòu)造函數(shù)可以使得各對象的數(shù)據(jù)成員的初始值不同,通過創(chuàng)建對象時將實參傳遞給構(gòu)造函數(shù),達(dá)到初始化目的。Page 1515# include# includeclass Student public: Student(char* pName) cout constructing student pName endl; s

11、trncpy(name,pName,sizeof(name); namesizeof(name)-1=0; Student( )cout destructing name endl; /其他公共成員 protected: char name20;int main( ) Student ss(Jenny); /.運行結(jié)果:constructing student Jennydestructing Jenny12.5 帶參數(shù)的構(gòu)造函數(shù)16構(gòu)造函數(shù)可以有任意多個參數(shù) # include # include class Student public: Student(char* pName, int

12、xHours, float xgpa) cout constructing student pName endl; strncpy(name,pName,sizeof(name); namesizeof(name)-1=0; semesHours=xHours; gpa=xgpa; Student( )cout destructing name endl; /其他公共成員 protected: char name20; int semesHours; float gpa; ; int main( ) Student ss(Jenny, 22, 3.5); 運行結(jié)果為:constructing

13、student Jennydestructing Jenny1712.6 重載構(gòu)造函數(shù)重載構(gòu)造函數(shù):在一個類中出現(xiàn)多個構(gòu)造函數(shù),但是它們所帶的參數(shù)個數(shù)、參數(shù)類型有所不同 。 #include class Tdate public: Tdate( ); /默認(rèn)構(gòu)造函數(shù) Tdate(int d); Tdate(int m, int d); Tdate(int m, int d, int y); /其他公共成員 protected: int month; int day; int year; ;Page 1818Tdate:Tdate( ) month=4; day=15; year=1995; c

14、out month / day /year endl;Tdate:Tdate(int d) month=4; day=d; year=1996; cout month / day/ year endl;Tdate:Tdate(int m, int d) month=m; day=d; year=1997; cout month / day/ year endl; Tdate:Tdate(int m,int d, int y) month=m; day=d; year=y; cout month / day/ year endl;12.6 重載構(gòu)造函數(shù) int main( ) Tdate ada

15、y; Tdate bday(10); Tdate cday(2, 12); Tdate dday(1, 2, 1998); 運行結(jié)果:4/15/19954/10/1996 2/12/19971/2/199819多個構(gòu)造函數(shù)可以共享初始化過程,先定義一個共享成員函數(shù),然后每個構(gòu)造函數(shù)都調(diào)用之。# include class Tdate public: Tdate( ) Init(4,15,1995); Tdate(int d) Init(4,d,1996); Tdate(int m,int d) Init(m,d,1997); Tdate(int m,int d,int y) Init(m,d,

16、y); /其他公共成員 protected: int month, day, year void Init(int m,int d,int y) month=m; day=d; year=y; cout month / day / year endl; ; Page 2012.6 重載構(gòu)造函數(shù)20 int main( ) Tdate aday; Tdate bday(10); Tdate cday(2, 12); Tdate dday(1, 2, 1998); 運行結(jié)果:4/15/1995 4/10/1996 2/12/1997 1/2/1998Page 2112.6 重載構(gòu)造函數(shù)21多個構(gòu)造

17、函數(shù)可以通過給一個構(gòu)造函數(shù)以參數(shù)默認(rèn)值,使多個構(gòu)造函數(shù)結(jié)合成一個。 # include class Tdate public: Tdate(int m=4, int d=15, int y=1995) month=m; day=d; year=y; cout month / day/ year endl; /其他公共成員 protected: int month; int day; int year; ;Page 22int main( ) Tdate aday; Tdate bday(2); Tdate cday(3, 12); Tdate dday(1, 2, 1998); 12.6 重載

18、構(gòu)造函數(shù)22重載構(gòu)造函數(shù)若與參數(shù)默認(rèn)值的構(gòu)造函數(shù)發(fā)生沖突,則創(chuàng)建對象的語句會導(dǎo)致編譯錯誤。例: class Tdate public: Tdate(int d)month=4; day=d; year=1998; Tdate(int m, int d=12)month=m; day=d; year=1997; /其他公共成員 protected: int month; int day; int year; ; int main( ) Tdate aday(11); /error:匹配哪個構(gòu)造函數(shù) 12.6 重載構(gòu)造函數(shù)2312.7 默認(rèn)構(gòu)造函數(shù)C+規(guī)定,每個類必須有一個構(gòu)造函數(shù),沒有就不能創(chuàng)建

19、任何對象。若未提供一個類的構(gòu)造函數(shù),則C+提供一個默認(rèn)的構(gòu)造函數(shù),它是個無參構(gòu)造函數(shù),僅負(fù)責(zé)創(chuàng)建對象,而不做任何初始化工作。只要一個類定義了一個構(gòu)造函數(shù),C+就不再提供默認(rèn)的默認(rèn)構(gòu)造函數(shù)。與變量定義類似,在用默認(rèn)構(gòu)造函數(shù)創(chuàng)建對象時,如果創(chuàng)建的是全局對象或靜態(tài)對象,則對象的位模式全為0,否則,對象值是隨機(jī)的。24 例: class Student /無構(gòu)造函數(shù) protected: char name20; ; int main( ) Student noName; /ok:noName的內(nèi)容為隨機(jī)值 public: Student( ) /一個空的無 /參構(gòu)造函數(shù)等價于12.7 默認(rèn)構(gòu)造函數(shù)2

20、5下面的代碼定義了一個帶參數(shù)的構(gòu)造函數(shù),面對創(chuàng)建無參對象,將不能正確的編譯: #include class Student public: Student(char* pName) strncpy(name,pName,sizeof(name); namesizeof(name)-1=0; protected: char name20; ; int main( ) Student noName; /error:無匹配的構(gòu)造函數(shù) 12.7 默認(rèn)構(gòu)造函數(shù)26如果增加一個無參的構(gòu)造函數(shù),就可解決這個問題: #include class Student public: Student(char* pN

21、ame) strncpy(name,pName,sizeof(name); namesizeof(name)-1=0; Student( ) protected: char name20; ; int main( ) Student noName; /ok Student ss(Jenny); /ok 12.7 默認(rèn)構(gòu)造函數(shù)27說明的含糊性先前的例子中創(chuàng)建Tdate類對象的方法是: Tdate aday; /為什么創(chuàng)建無參的對象無括號? Tdate bday(2); /對象的參數(shù)放在括號中 Tdate aday( ); /為什么不能這樣聲明?根據(jù)C+的語法規(guī)定,這樣是聲明了一個名叫aday的普

22、通函數(shù),返回Tdate類對象,并且沒有參數(shù)。 又例如下面的代碼,一個是創(chuàng)建對象,一個是聲明函數(shù): Tdate oneday(10); /創(chuàng)建對象 Tdate oneday(int); /聲明函數(shù)12.7 默認(rèn)構(gòu)造函數(shù)2812.8 類成員初始化的困惑當(dāng)一個類中的某個成員是另一個類的對象時,如何初始化這個成員? # include # include int nextStudentID=0; class StudentID public: StudentID( ) value=+nextStudentID; cout Assigning student id value endl; Student

23、ID( ) -nextStudentID; cout Destructing id value endl; protected: int value; ; 29class Student public: Student(char* pName=noName) cout Constructing student pName endl; strcpy(name,pName); namesizeof(name)-1=0; protected: char name20; StudentID id; ; int main( ) Student s(Randy); Page 30運行結(jié)果:Assignin

24、g student id 1Constructing student RandyDestructing id 112.8 類成員初始化的困惑3012.8 類成員初始化的困惑如果想調(diào)用的函數(shù)不是默認(rèn)構(gòu)造函數(shù)又如何呢?例如,下面的程序在創(chuàng)建學(xué)生對象時,賦予一個學(xué)號,希望將這個學(xué)生傳給成員學(xué)號類對象id保存: # include # include class StudentID public: StudentID(int id=0) value=id; cout Assigning student id value endl; StudentID( ) cout Destructing id va

25、lue endl; protected: int value; ;31class Student public: Student(char* pName=noName,int ssID=0) cout “Constructing student”pName endl; strcpy(name,pName); namesizeof(name)-1=0; StudentID id(ssID); /實際上創(chuàng)建了一個局部對象id protected: char name20; StudentID id; ; int main( ) Student s(Randy,9818); 12.8 類成員初始化的

26、困惑32運行結(jié)果為: Assigning student id 0 Constructing student Randy Assigning student id 9818 Destructing id 9818 Destructing id 0此結(jié)果并未達(dá)到在初始化時賦予的學(xué)號傳給學(xué)號類對象id的目的。12.8 類成員初始化的困惑33那么,能否像下面這樣在Student類中直接給id對象初始化呢? class Student public: Student(char *pname=“noName”, int ssID); protected: char name20; StudentID i

27、d(9818); /error:類定義是不分配空間和初始化的 ;類是一個抽象概念,并不是一個實體,并不含有屬性值,而只有對象才占有一定的空間,含有明確的屬性值。12.8 類成員初始化的困惑3412.9 構(gòu)造類成員類成員的構(gòu)造應(yīng)該在建立對象空間的結(jié)構(gòu)時反映出來,即需要出現(xiàn)在函數(shù)調(diào)用剛剛轉(zhuǎn)入之時,函數(shù)體執(zhí)行(開括號)之前。類成員的初始化完全可以利用構(gòu)造函數(shù)完成,在構(gòu)造函數(shù)的原型中利用冒號語法,在冒號后面進(jìn)行成員初始化: 構(gòu)造函數(shù)(參數(shù)列表):成員初始化列表 35 /ch12_12.cpp# include # include class StudentID public: StudentID(in

28、t id=0) value=id; cout Assigning student id value endl; StudentID( ) cout Destructing id value endl; protected: int value; ;12.9 構(gòu)造類成員36class Student public: Student(char* pName=no name, int ssID=0) :id(ssID) /冒號表示后面要對類的數(shù)據(jù)成員的構(gòu)造函數(shù)進(jìn)行調(diào)用。 /這里是調(diào)用以ssID為實參的StudentID構(gòu)造函數(shù)。 cout Constructing student pName end

29、l; strncpy(name,pName,sizeof(name); namesizeof(name)-1=0; protected: char name20; StudentID id; ; int main( ) Student s(Randy,9818); Student t(Jenny); 運行結(jié)果: Assigning student id 9818 Constructing student Randy Assigning student id 0 Constructing student Jenny Destructing id 0 Destructing id 981837St

30、udent構(gòu)造函數(shù)頭后面如果是id( )的形式,表示調(diào)用StudentID的默認(rèn)構(gòu)造函數(shù),并且可以省略。 Student(char* pName=no name, int ssID=0) :id( ) / 也可以寫成: Student(char* pName=no name, int ssID=0) / 12.9 構(gòu)造類成員38構(gòu)造類成員時調(diào)用類成員的哪個構(gòu)造函數(shù)要是看參數(shù)匹配的情況。例如,在ch12_12.cpp中,如果StudentID構(gòu)造函數(shù)中,參數(shù)沒有默認(rèn)值,即原型為: StudentID(int id); 表明StudentID沒有默認(rèn)構(gòu)造函數(shù)。如果Student構(gòu)造函數(shù)的原型為:

31、Student(char *pName=no name, int ssID) ;是無冒號形式,表明Student將調(diào)用StudentID的默認(rèn)構(gòu)造函數(shù)。于是,主函數(shù)中的兩條創(chuàng)建Student對象的語句都要遇到不能匹配StudentID構(gòu)造函數(shù)的錯誤。 12.9 構(gòu)造類成員39冒號語法使得常量數(shù)據(jù)成員和引用數(shù)據(jù)成員的初始化成為可能。 例:class SillyClass public: SillyClass(int & i):ten(10),refI(i) protected: const int ten; /常量數(shù)據(jù)成員 int & refI; /引用數(shù)據(jù)成員 ; int main( ) in

32、t i; SillyClass sc(i); 12.9 構(gòu)造類成員40常量是不能被賦值的,引用變量也是不可重新指派的,一旦初始化,其值就永不改變。例:class SillyClass public: SillyClass(int &i) ten=10; /error:常量是不能被賦值 refI=i; /error:引用不可重新指派 protected: const int ten; int & refI; ; 12.9 構(gòu)造類成員41數(shù)據(jù)成員若是一般變量,則放在冒號后面與放在函數(shù)體中初始化一樣。 例:class SillyClass class SillyClass public: publi

33、c: SillyClass( ) SillyClass( ):d(10) /方法2 d=10;/方法1 protected: protected: int d; int d; ; ;12.9 構(gòu)造類成員42說明一個變量并初始化有兩種形式: int main( ) int m=10; /ok int n(20); /TC+3.0不允許,C+新標(biāo)準(zhǔn)允許 Student s=“Jenny”; /ok Student t(“Danny”); /ok:類的形式不受限制 注意:賦值表達(dá)式中不允許:m(10); 只能:m=10; 構(gòu)造函數(shù)的冒號后的初始化不允許用第一種形式: class SillyClass

34、 public: SillyClass2( ):d=10 /error protected: int d; ;12.9 構(gòu)造類成員4312.10 構(gòu)造對象的順序1. 局部和靜態(tài)對象,以聲明的順序構(gòu)造。# include # include class Student public: Student(char* pName=no name) cout constructing student pName endl; strncpy(name,pName,sizeof(name); namesizeof(name)-1=0; Student( ) cout destructing name endl; /其他公共成員 protected: char name20;44int main( ) Student s1(Jenny); Student s2(Jone); /. 運行結(jié)果: constructing student Jenny constructing student Jone destructing

溫馨提示

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

評論

0/150

提交評論