




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第17章C++類:第二部分
目標(biāo)
?可以動(dòng)態(tài)創(chuàng)建和破壞對(duì)象。
,可以指定const(常量)對(duì)象和const成員函數(shù)。
?理解friend函數(shù)和友類的目的。
?理解如何使用static數(shù)據(jù)成員和成員函數(shù)。
?理解容器類的概念。
?理解可以遍歷容器類的元素的迭代器類的概念。
?理解this指針的使用。
17.1簡(jiǎn)介
在本章中,我們繼續(xù)研究類和數(shù)據(jù)抽象。我們?cè)诘?8章中將討論更多的高級(jí)內(nèi)容,并建
立類和運(yùn)算符重載討論的基礎(chǔ)。第16章~第18章的討論鼓勵(lì)程序員使用對(duì)象,我們稱之為基
于對(duì)象的編程方法(OBP,object-basedprogramming)0然后,第19章和第20章介紹了繼承
和多態(tài)性,這是真正面向?qū)ο蟮木幊碳夹g(shù)(OOP,object-orientedprogramming)..在本章和后
面的章節(jié)中,我們使用在第8章中介紹的C樣式的字符串,這將幫助您掌握C指針的復(fù)雜內(nèi)
容,準(zhǔn)備進(jìn)入專業(yè)世界,在這里,您將看見(jiàn)過(guò)去20年中所遺留的大量C代碼。
17.2const(常量)對(duì)象和const成員函數(shù)
我們已經(jīng)強(qiáng)調(diào)了,最低特權(quán)原則是好的軟件工程所用的最基本原則之一。下面研究這個(gè)原
則如何應(yīng)用于對(duì)象。
一些對(duì)象需要修改,而另外一些不需要。程序員可以使用關(guān)鍵字const來(lái)指定對(duì)象不能修
改,而嘗試修改該對(duì)象將導(dǎo)致語(yǔ)法錯(cuò)誤。例如:
constTimenoon(12,0,0);
聲明了類Time的const對(duì)象noon,并將其初始化為12。
軟件工程經(jīng)驗(yàn)17.1__________________________________________________________
將對(duì)象聲明為const有助于實(shí)施最低特權(quán)原則。這樣,在編譯時(shí)可以捕獲修改對(duì)
象的嘗試,而不是導(dǎo)致執(zhí)行期間錯(cuò)誤。
軟件工程經(jīng)驗(yàn)17.2__________________________________________________________
使用const對(duì)于正確的類設(shè)計(jì)、程序設(shè)計(jì)和編碼是非常重要的。
性能提示17.1______________________________________________________________
聲明變量和對(duì)象是const并不僅僅是有效的軟件工程方法,因?yàn)楝F(xiàn)在的高級(jí)優(yōu)化
編譯程序可以對(duì)常量執(zhí)行某些優(yōu)化,而不能對(duì)變量進(jìn)行優(yōu)化,因此它也可以改善
性能。
C++編譯程序不允許任何成員函數(shù)調(diào)用const對(duì)象,除非成員函數(shù)本身也聲明為const。這
甚至對(duì)于不修改對(duì)象的get成員函數(shù)也是一樣的。聲明為const的成員函數(shù)不會(huì)修改對(duì)象,編
譯程序不允許這樣。
在函數(shù)原型中,通過(guò)在函數(shù)的參數(shù)列表后面插入關(guān)鍵字const,或者在函數(shù)定義中,在函
數(shù)體開(kāi)始的左大括號(hào)之前加入關(guān)鍵字const,就可以在原型和定義中指定函數(shù)是const。例如,
下面的類A的成員函數(shù):
intA::getValue()const{returnprivateDataMember;}
僅僅返回對(duì)象的一個(gè)數(shù)據(jù)成員的值,而且正確聲明為const。
常見(jiàn)的編程錯(cuò)誤17.1________________________________________________________
將修改對(duì)象數(shù)據(jù)成員的成員函數(shù)定義為const將導(dǎo)致語(yǔ)法錯(cuò)誤。
常見(jiàn)的編程錯(cuò)誤17.2________________________________________________________
在類的相同實(shí)例上,如果將調(diào)用類的非const成員函數(shù)的成員函數(shù)定義為const,
將導(dǎo)致語(yǔ)法錯(cuò)誤。
常見(jiàn)的編程錯(cuò)誤17.3________________________________________________________
在const對(duì)象上調(diào)用非const成員函數(shù)將導(dǎo)致語(yǔ)法錯(cuò)誤。
軟件工程經(jīng)驗(yàn)17.3__________________________________________________________
const成員函數(shù)可以用非const版本來(lái)重載。選擇使用哪一個(gè)重載成員函數(shù)是由編
譯程序根據(jù)對(duì)象是否是const來(lái)決定的。
這里提出了有關(guān)構(gòu)造函數(shù)和析構(gòu)函數(shù)的有趣問(wèn)題,它們每一個(gè)都需要經(jīng)常修改對(duì)象。并且
不允許對(duì)const對(duì)象的構(gòu)造函數(shù)和析構(gòu)函數(shù)使用const聲明。必須允許構(gòu)造函數(shù)修改對(duì)象,這
樣可以正確地初始化對(duì)象。析構(gòu)函數(shù)必須可以在破壞對(duì)象之前終止清理雜務(wù)。
常見(jiàn)的編程錯(cuò)誤17.4________________________________________________________
產(chǎn)嘗試聲明構(gòu)造函數(shù)或者析構(gòu)函數(shù)為const將導(dǎo)致語(yǔ)法錯(cuò)誤。
圖17.1實(shí)例化了兩個(gè)Time對(duì)象:一個(gè)是非const對(duì)象,另一個(gè)是const對(duì)象。該程序嘗
試用非const成員函數(shù)setHour(第102行)和printstandard(在第108行)來(lái)修改const對(duì)象
noon。程序也說(shuō)明了在對(duì)象上調(diào)用成員函數(shù)的3個(gè)其他組合:在非const對(duì)象上調(diào)用非const
成員函數(shù)(第100行),在非const對(duì)象上調(diào)用const成員函數(shù)(第104行),以及在const對(duì)象
上調(diào)用const成員函數(shù)(第106行和107行)。兩個(gè)流行的編譯程序?yàn)榉莄onst成員函數(shù)在const
544第2部分C++編程
對(duì)象上調(diào)用而產(chǎn)生的消息顯示在輸出窗口中。
1//Fig.17.1:time5.h
2//DeclarationoftheclassTime.
3//Memberfunctionsdefinedintime5.cpp
4#ifndefTIME5_H
5#defineTIME5_H
6
7classTime{
8public:
9Time(int=0,int=0,int=0);//defaultconstructor
10
11//setfunctions
12voidsetTime(int,int,int);//settime
13voidsetHour(int);//sethour
14voidsetMinute(int);//setminute
15voidsetSecond(int);//setsecond
16
17//getfunctions(normallydeclaredconst)
18intgetHour()const;//returnhour
19intgetMinute()const;//returnminute
20intgetSecond()const;//returnsecond
21
22//printfunctions(normallydeclaredconst)
23voidprintMilitary()const;//printmilitarytime
24voidprintstandard();//printstandardtime
25private:
26inthour;//0-23
27intminute;//0-59
28intsecond;//0-59
29);
30
31#endif
圖17.1通過(guò)const對(duì)象和const成員函數(shù)來(lái)使用Time類:time5.h
32//Fig.17.1:time5.cpp
33//MemberfunctiondefinitionsforTimeclass.
34#include<iostream>
35
36usingstd::cout;
37
38#include"time5.hn
39
40//Constructorfunctiontoinitializeprivatedata.
41//Defaultvaluesare0(seeclassdefinition).
42Time::Time(inthr,intmin,intsec)
43{setTime(hr.min.sec);)
44
45//Setthevaluesofhour,minute,andsecond.
46voidTime::setTime(inth,intm,ints)
47(
48setHour(h);
49setMinute(m);
50setSecond(s);
51}
52
53//Setthehourvalue
54voidTime::setHour(inth)
55{hour=(h>=0&&h<24)?h:0;}
56
57//Settheminutevalue
58voidTime::setMinute(intm)
59{minute=(m>=0&&m<60)?m:0;}
60
61//Setthesecondvalue
62voidTime::setSecond(ints)
63{second=(s>=0&&s<60)?s:0;}
64
65//Getthehourvalue
66intTime::getHour()const{returnhour;}
67
68//Gettheminutevalue
69intTime::getMinute()const{returnminute;}
70
71//Getthesecondvalue
72intTime::getSecond()const{returnsecond;}
73
74//Displaymilitaryformattime:HH:MM
75voidTime::printMilitary()const
76(
77cout<<(hour<10?*'0'*:,***)<<hour<<
78<<(minute<10?*'0'*:"")<<minute;
79)
80
81//Displaystandardformattime:HH:MM:SSAM(orPM)
82voidTime::printstandard()//shouldbeconst
83
84cout<<((hour==12)?12:hour%12)<<n:n
85<<(minute<10?"O',nn)<<minute<<“:"
86<<(second<10?n0n““)<<second
87<<(hour<12?nAM"HPM”)
88
圖17.1通過(guò)const對(duì)象和const成員函數(shù)來(lái)使用Time類:lime5.cpp
89//Fig.17.1:figl7_01.cpp
546第2部分C++編程
90//Attemptingtoaccessaconstobjectwith
91//non-constmemberfunctions.
92#include"time5.hn
93
94intmain()
95(
96TimewakeUp(6,45,0);//non-constantobject
97constTimenoon(12,0,0);//constantobject
98
99//MEMBERFUNCTIONOBJECT
100wakeUp.setHour(18);//non-constnon-const
101
102noon.setHour(12);//non-constconst
103
104wakeUp.getHour();//constnon-const
105
106noon.getMinute();//constconst
107noon.printMilitary();//constconst
108noon.printstandard();//non-constconst
109return0;
110}
BorlandC++命令行編譯程序警告消息
Figl7_01.cpp:
WarningW8037Figl7_01.cpp14:Non-constfunctionTime::setHour(int)
calledforconstobjectinfunctionmain()
WarningW8037Figl7_01.cpp20:Non-constfunctionTime::printStandard()
calledforconstobjectinfunctionmain()
TurboIncrementalLink5.00Copyright(c)1997,2000Borland
MicrosoftVisualC++編譯程序錯(cuò)誤消息
Compiling...
Figl7_01.cpp:
d:figl7_01.cpp(14):errorC2662:*setHour*:cannotconvert*this*
pointerfrom*constclassTime*to'classTime&*
Conversionlosesqualifiers
d:\figl7_01.cpp(20):errorC2662:1printStandard*:cannotconvert
fthis*pointerfrom1constclassTime1to*classTime&'
Conversionlosesqualifiers
Time5.cpp
Errorexecutingcl.exe
Test.exe-2error(s),0warning(s)
圖17.1通過(guò)const對(duì)象和const成員函數(shù)來(lái)使用Time類:figl7_01.cpp
?"良好的編程習(xí)慣17.1________________________________________________________
|^|將所有不需要修改當(dāng)前對(duì)象的成員函數(shù)聲明為const,這樣,如果需要,可以在
const對(duì)象上使用它們。
注意,即使構(gòu)造函數(shù)必須是非const成員函數(shù),它仍然為const對(duì)象調(diào)用。第42行和43
行的Time構(gòu)造函數(shù)的定義:
Time::Time(inthr,intmin,intsec)
{setTime(hr,min,sec);}
說(shuō)明Time構(gòu)造函數(shù)調(diào)用了非const成員函數(shù)setTime以執(zhí)行Time對(duì)象的初始化。對(duì)于const
對(duì)象,允許從構(gòu)造函數(shù)調(diào)用中調(diào)用非const成員函數(shù)。對(duì)象的const特性是在構(gòu)造函數(shù)完成對(duì)
象的初始化到調(diào)用該對(duì)象的析構(gòu)函數(shù)期間強(qiáng)制執(zhí)行的。
軟件工程經(jīng)驗(yàn)17.4__________________________________________________________
不能通過(guò)賦值來(lái)修改const對(duì)象,所以,該對(duì)象必須初始化。當(dāng)類的數(shù)據(jù)成員聲
明為const時(shí),則使用成員初始值來(lái)為構(gòu)造函數(shù)提供類對(duì)象的數(shù)據(jù)成員的初始值。
還要注意,第108行(源文件中的第20行):
noon.printstandard();//non-constconst
產(chǎn)生了編譯程序錯(cuò)誤,即使類Time的成員函數(shù)printstandard沒(méi)有修改調(diào)用它的對(duì)象。沒(méi)有修
改對(duì)象并不足以說(shuō)明它是const方法。該方法必須也明確聲明為const。
圖17.2說(shuō)明使用成員初始值來(lái)初始化類Increment的const數(shù)據(jù)成員increment?Increment
的構(gòu)造函數(shù)將修改如下:
1//Fig.17.2:figl7_02.cpp
2//Usingamemberinitializertoinitializea
3//constantofabuilt-indatatype.
4#include<iostream>
5
6usingstd::cout;
7usingstd::endl;
8
9classIncrement{
10public:
11Increment(intc=0,inti=1);
12voidaddlncrement(){count+=increment;}
13voidprint()const;
14
15private:
16intcount;
17constintincrement;//constdatamember
18};
19
20//ConstructorforclassIncrement
548第2部分C++編程
21Increment::Increment(intc,inti)
22:increment(i)//initializerforconstmember
23{count=c;}
24
25//Printthedata
26voidIncrement::print()const
27(
28cout<<11count="<<count
29<<”,increment=*'<<increment<<endl;
30}
31
32intmain()
33(
34Incrementvalue(10,5);
35
36cout<<"Beforeincrementing:f,;
37value.print();
38
39for(intj=0;j<3;j++){
40value.addincrement();
41cout<<"Afterincrementn<<j+1<<*':";
42value.print();
43)
44
45return0;
46}
Beforeincrementing:count=10,increment=5
Afterincrement1:count=15,increment=5
Afterincrement2:count=20,increment=5
Afterincrement3:count-25,increment=5
圖17.2使用成員初始值來(lái)初始化內(nèi)置數(shù)據(jù)類型的常量
Increment::Increment(intc,inti)
:increment(i)
{count=c;}
符號(hào):increment⑴將increment初始化為值i,如果需要多個(gè)初始值,則只需將它們包含在
冒號(hào)后面用逗號(hào)分開(kāi)的列表中??梢杂贸蓡T初始值語(yǔ)法來(lái)初始化所有數(shù)據(jù)成員,但必須用這種
方式來(lái)初始化const和引用。本章的后面,我們將看見(jiàn)必須用這種方式初始化成員對(duì)象。在第
19章中,當(dāng)我們研究繼承時(shí),將看見(jiàn)派生類的基類部分也必須用這種方式初始化。
測(cè)試和調(diào)試提示17.1
如果函數(shù)不修改對(duì)象,則總是聲明成員函數(shù)為const。這可以幫助避免許多錯(cuò)誤。
圖17.3說(shuō)明了兩個(gè)流行C++編譯程序?yàn)閲L試用賦值語(yǔ)句,而不是用成員初始值來(lái)初始化
increment的程序所產(chǎn)生的兩個(gè)編譯程序錯(cuò)誤。
1//Fig.17.3:figl7_03.cpp
2//Attemptingtoinitializeaconstantof
3//abuilt-indatatypewithanassignment.
4#include<iostream>
5
6usingstd::cout;
7usingstd::endl;
8
9classIncrement{
10public:
11Increment(intc=0,inti=1);
12voidaddincrement(){count+=increment;}
13voidprint()const;
14private:
15intcount;
16constintincrement;
17};
18
19//ConstructorforclassIncrement
20Increment::Increment(intc,inti)
21{//Constantmember*increment'isnotinitialized
22count=c;
23increment=i;//ERROR:Cannotmodifyaconstobject
24}
25
26//Printthedata
27voidIncrement::print()const
28(
29cout<<"count=n<<count
30<<”,increment=*'<<increment<<endl;
31}
32
33intmain()
34(
35Incrementvalue(10,5);
36
37cout<<"Beforeincrementing:**;
38value.print();
39
40for(intj=0;j<3;j++){
41value.addlncrement();
42cout<<"Afterincrement"<<j<<":11;
43value.print();
550第2部分C++編程
44}
45
46return0;
47}
BorlandC++命令行編譯程序警告和錯(cuò)誤消息
Figl7__03.cpp:
WarningW8038Figl7_03.cpp21:Constantmember'Increment::increment,
isnotinitializedinfunctionIncrement::Increment(int,int)
ErrorE2024Figl7_03.cpp23:Cannotmodifyaconstobjectinfunction
Increment::Increment(int,int)
WarningW8057Figl7_03.cpp24:Parameter'i'isneverusedinfunction
Increment::Increment(int,int)
***1errorsinCompile***
MicrosoftVisualC++編譯程序錯(cuò)誤消息
Compiling...
Figl7_03,cpp
D:\Figl7_03.cpp(21):errorC2758:'incrementf:mustbeinitializedin
constructorbase/memberinitializerlist
D:\Figl7_03.cpp(16):seedeclarationof*increment'
D:\Figl7_03.cpp(23):errorC2166:1-valuespecifiesconstobject
Errorexecutingcl.exe.
test.exe-2error(s),0warning(s)
圖17.3嘗試通過(guò)賦值語(yǔ)句來(lái)初始化內(nèi)置數(shù)據(jù)類型常量是錯(cuò)誤的
7^3常見(jiàn)的編程錯(cuò)誤17.5_________________________________________________________
沒(méi)有為const數(shù)據(jù)成員提供成員初始值將導(dǎo)致語(yǔ)法錯(cuò)誤。
軟件工程經(jīng)驗(yàn)17.5__________________________________________________________
常量類成員(const對(duì)象和const"變量")必須用成員初始值語(yǔ)法來(lái)初始化;不
允許賦值。
注意,第27行的print函數(shù)聲明為const<>因?yàn)槲覀兛赡苡肋h(yuǎn)不會(huì)有constincrement對(duì)象,
因此將這個(gè)函數(shù)標(biāo)記為const是合理的,但卻是奇怪的。
軟件工程經(jīng)驗(yàn)17.6__________________________________________________________
將不修改所操作對(duì)象的類的所有成員函數(shù)聲明為const是好的習(xí)慣。某些情況下,
因?yàn)椴⒉幌M麆?chuàng)建那個(gè)類的const對(duì)象,因此這可能是反常的。聲明這樣的成員
函數(shù)為const確實(shí)有好處。如果在那個(gè)成員函數(shù)中無(wú)意修改了對(duì)象,則編譯程序
將發(fā)出語(yǔ)法錯(cuò)誤消息。
測(cè)試和調(diào)試提示17.2
類似C++這樣的語(yǔ)言,隨著語(yǔ)言的發(fā)展,其目標(biāo)也會(huì)變化。在語(yǔ)言中很可能添加更
多的關(guān)鍵字。避免使用類似“object”這樣的單詞作為標(biāo)識(shí)符.即使“object”
當(dāng)前并不是C++中的關(guān)鍵字,它也可能成為關(guān)鍵字,所以將來(lái)用新的編譯程序來(lái)編
譯時(shí),可能現(xiàn)有的代碼會(huì)不符合要求。
17.3復(fù)合:作為類成員的對(duì)象
AlarmClock類對(duì)象需要知道何時(shí)發(fā)出警告,所以為什么不包含Time對(duì)象作為
AlarmClock對(duì)象的一個(gè)成員?這樣的功能稱為復(fù)合(composition)。類可以用其他類的對(duì)
象作為成員。
軟件工程經(jīng)驗(yàn)17.7____________________________________________________
軟件重用性的最常見(jiàn)形式就是復(fù)合,其中類用其他類的對(duì)象作為成員。
當(dāng)創(chuàng)建對(duì)象時(shí),將自動(dòng)調(diào)用它的構(gòu)造函數(shù),所以我們需要指定向成員對(duì)象構(gòu)造函數(shù)傳遞多
少個(gè)參數(shù)。應(yīng)該按照聲明對(duì)象的順序來(lái)構(gòu)造成員對(duì)象(不是按照構(gòu)造函數(shù)成員初始值列表中列
出的順序),而且在包含它們的類對(duì)象(有時(shí)候稱為宿主對(duì)象)被構(gòu)造之前構(gòu)造。
圖17.4使用類Employee和類Date來(lái)說(shuō)明某個(gè)對(duì)象作為其他對(duì)象的成員。類Employee包
含private數(shù)據(jù)成員firstName、lastName、birthDate和hireDate。成員birthDate和hireDate是
類date的const對(duì)象,它們包含private數(shù)據(jù)成員month、day和year。該程序?qū)嵗疎mployee
對(duì)象,并初始化和顯示它的數(shù)據(jù)成員。注意Employee構(gòu)造函數(shù)定義中的函數(shù)頭的語(yǔ)法:
Employee::Employee(char*fname,char*lname,
intbmonth,intbday,intbyear,
inthmonth,inthday,inthyear)
:birthDate(bmonth,bday,byear),
hireDate(hmonth,hday,hyear)
1//Fig.17.4:datel.h
2//DeclarationoftheDateclass.
3//Memberfunctionsdefinedindatel.cpp
4#ifndefDATE1_H
5#defineDATE1_H
6
7classDate{
8public:
9Date(int=1,int=1,int=1900);//defaultconstructor
10voidprint()const;//printdateinmonth/day/yearformat
11-Date();//providedtoconfirmdestructionorder
12private:
13intmonth;//1-12
14intday;//1-31basedonmonth
15intyear;//anyyear
552第2部分C++編程
1&
17//utilityfunctiontotestproperdayformonthandyear
18intcheckDay(int);
19);
20
21#endif
圖17.4使用成員對(duì)象初始值:datel.h
22//Fig.17.4:datel.cpp
23//MemberfunctiondefinitionsforDateclass.
24#include<iostream>
25
26usingstd::cout;
27usingstd::endl;
28
29#include"datel.h”
30
31//Constructor:Confirmpropervalueformonth;
32//callutilityfunctioncheckDaytoconfirmproper
33//valueforday.
34Date::Date(intmn,intdy,intyr)
35(
36if(mn>0&&mn<=12)//validatethemonth
37month=mn;
38else(
39month=1;
40cout<<"Month”<<mn<<'*invalid.Settomonth1.\n;
41}
42
43year=yr;//shouldvalidateyr
44day=checkDay(dy);//validatetheday
45
46cout<<"Dateobjectconstructorfordate";
47print();//interesting:aprintwithnoarguments
48cout<<endl;
49)
50
51//PrintDateobjectinformmonth/day/year
52voidDate::print()const
53{cout<<month<<*/'<<day<<*/*<<year;}
54
55//Destructor:providedtoconfirmdestructionorder
56Date::~Date()
57(
58cout<<"Dateobjectdestructorfordate
59print();
60cout<<endl;
61
62
63//Utilityfunctiontoconfirmproperdayvalue
64//basedonmonthandyear.
65//Istheyear2000aleapyear?
66intDate::checkDay(inttestDay)
67(
68staticconstintdaysPerMonth[13]=
69{0,31,28,31,30,31,30,31,31,30,31,30,31);
70
71if(testDay>0&&testDay<=daysPerMonth[month])
72returntestDay;
73
74if(month==2&&//February:Checkforleapyear
75testDay==29&&
76(year%400==0II
77(year%4==0&&year%100!=0)))
78returntestDay;
79
80cout<<"Day"<<testDay<<”invalid.Settoday1.\n";
81
82return1;//leaveobjectinconsistentstateifbadvalue
83
圖17.4使用成員對(duì)象初始值:datel.cpp
84//Fig.17.4:emply1.h
85//DeclarationoftheEmployeeclass.
86//Memberfunctionsdefinedinemply1.cpp
87#ifndefEMPLY1_H
88#defineEMPLY1_H
89
90#include"datel.hn
91
92classEmployee{
93public:
94Employee(char*,char*,int,int,int,int,int,int);
95voidprint()const;
96-Employee();//providedtoconfirmdestructionorder
97private:
98charfirstName[25];
99charlastName[25];
100constDatebirthDate;
101constDatehireDate;
102};
103
104#endif
圖17.4使用成員對(duì)象初始值:emplyl.h
554第2部分C++編程
105//Fig.17.4:emplyl.cpp
106//MemberfunctiondefinitionsforEmployeeclass.
107#include<iostream>
108
109usingstd::cout;
110usingstd::endl;
111
112#include<cstring>
113#include"emplyl.h”
114#include"datel.hu
115
116Employee::Employee(char*fname,char*lname,
117intbmonth,intbdayzintbyear,
118inthmonth,inthday,inthyear)
119:birthDate(bmonth,bday,byear),
120hireDate(hmonth,hdayzhyear)
121(
122//copyfnameintofirstNameandbesurethatitfits
123intlength=strlen(fname);
124length=(length<25?length:24);
125strncpy(firstName,fname,length);
126firstName[length]=1\0*;
127
128//copyInameintolastNameandbesurethatitfits
129length=strlen(Iname);
130length=(length<25?length:24);
131strncpy(lastName,Iname,length);
132lastName[length]=*\0';
133
134cout<<"Employeeobjectconstructor:"
135<<firstName<<'*<<lastName<<endl;
136
137
138voidEmployee::print()const
139(
140cout<<lastName<<","<<firstName<<*'\nHired:
141hireDate.print();
142cout<<”Birthdate:n;
143birthDate.print();
144cout<<endl;
145}
146
147//Destructor:providedtoconfirmdestructionorder
148Employee::^Employee()
149(
150cout<<"Employeeobjectdestructor:"
151<<lastName<<","<<firstName<<endl;
152}
圖17.4使用成員對(duì)象初始值:emplyl.cpp
153//Fig.17.4:figl7_04.cpp
154//Demonstratingcomposition:anobjectwithmemberobjects.
155#include<iostream>
156
157usingstd::cout;
158usingstd::endl;
159
160#includenemplyl.h"
161
162intmain()
163(
164Employeee(“Bob”,“Jones”,7,24z1949,3,12,1988);
165
166cout<<'\n*;
167e.print();
168
169cout<<n\nTestDateconstructorwithinvalidvalues:\nH;
170Dated(14,35,1994);//invalidDatevalues
171cout<<endl;
172return0;
173}
Dateobjectconstructorfordate7/24/1949
Dateobjectconstructorfordate3/12/1988
Employeeobjectconstructor:BobJones
Jones,Bob
Hired:3/12/1988Birthdate:7/24/1949
TestDateConstructorwithinvalidvalues:
Month14invalid.Settomonth1.
Day35invalid.Settoday1.
Dateobjectconstructorfordate1/1/1994
Dateobjectdestructorfordate1/1/1994
Employeeobjectdestructor:Jones,Bob
Dateobjectdestructorfordate3/12/1988
Dateobjectdestructorfordate7/24/1949
17.4使用成員對(duì)象初始值:figl7_04.cpp
Employee構(gòu)造函數(shù)有8個(gè)參數(shù)(fname、Iname、bmonth、bday、byear、hmonth>hday和
hyear),頭部中的冒號(hào)(:)分開(kāi)了成員初始值和參數(shù)列表。成員初始值指定Employee參數(shù)傳
556第2部分C++編程
遞給成員Date對(duì)象的構(gòu)造函數(shù)。參數(shù)bmonth、bday和byear傳遞給對(duì)象birthDate的構(gòu)造函數(shù),
參數(shù)hmonth、hday和hyear傳遞給對(duì)象hireDate的構(gòu)造函數(shù)。用逗號(hào)分開(kāi)多個(gè)成員初始值。
記住,const成員和引用也是在成員初始值列表中初始化的(在第19章中,我們將看見(jiàn)派
生類的基類部分也用這種方式初始化)。類date和類Employee都包含析構(gòu)函數(shù),當(dāng)破壞Date
對(duì)象或者Employee對(duì)象時(shí),它們將分別打印消息。這使得我們可以在程序輸出中確信對(duì)象是
從內(nèi)向外構(gòu)造的,而且從外向內(nèi)按照相反的順序來(lái)破壞(也就是說(shuō),Date成員對(duì)象在包含它
們的Employee對(duì)象破壞之后破壞)。
成員對(duì)象并不需要通過(guò)成員初始值來(lái)明確初始化。如果沒(méi)有提供成員初始值,則將隱含調(diào)
用成員對(duì)象的默認(rèn)構(gòu)造函數(shù)。如果默認(rèn)構(gòu)造函數(shù)創(chuàng)建了值,則用set函數(shù)來(lái)覆蓋。然而,對(duì)于
復(fù)雜的初始化,這種方法需要相當(dāng)多的額外工作和時(shí)間。
7^x1常見(jiàn)的編程錯(cuò)誤17.6________________________________________________________
當(dāng)沒(méi)有為成員對(duì)象提供成員初始值時(shí),沒(méi)有為成員對(duì)象類提供默認(rèn)構(gòu)造函數(shù)將導(dǎo)
致語(yǔ)法錯(cuò)誤。
性能提示17.2______________________________________________________________
@用成員初始值來(lái)明確地初始化成員對(duì)象。這避免了“雙重初始化”成員對(duì)象的開(kāi)
銷:在調(diào)用成員對(duì)象的默認(rèn)構(gòu)造函數(shù)時(shí)初始化一次,在
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 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ì)用戶上傳內(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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 賀蘭山東麓葡萄酒展會(huì)銷售技巧培訓(xùn)
- 培訓(xùn)計(jì)劃制定方案
- 《課程預(yù)習(xí)知識(shí)點(diǎn)》課件
- 車檢設(shè)備轉(zhuǎn)讓合同協(xié)議
- 活動(dòng)主持協(xié)議書(shū)
- 路面塌方清理協(xié)議書(shū)范本
- 買賣廢鐵合同協(xié)議書(shū)
- 配件供銷合作協(xié)議合同
- 運(yùn)輸品賠償協(xié)議書(shū)范本
- 醫(yī)學(xué)亂象典型案例剖析
- 2025年北京市朝陽(yáng)區(qū)高三二模-政治+答案
- 《光纖激光切割技術(shù)》課件
- 10.信息光子技術(shù)發(fā)展與應(yīng)用研究報(bào)告(2024年)
- 2025年下半年商務(wù)部外貿(mào)發(fā)展事務(wù)局第二次招聘8人易考易錯(cuò)模擬試題(共500題)試卷后附參考答案
- 2024年山西杏花村汾酒集團(tuán)有限責(zé)任公司招聘筆試真題
- 《行政法與行政訴訟法》課件各章節(jié)內(nèi)容-第一章 行政法概述
- 浙江2025年浙江省地質(zhì)院本級(jí)及所屬部分事業(yè)單位招聘筆試歷年參考題庫(kù)附帶答案詳解
- 2025年廣東廣州中物儲(chǔ)國(guó)際貨運(yùn)代理有限公司招聘筆試參考題庫(kù)含答案解析
- MOOC 學(xué)術(shù)英語(yǔ)寫(xiě)作-東南大學(xué) 中國(guó)大學(xué)慕課答案
- 愚公移山英文 -中國(guó)故事英文版課件
- 原輔材料留樣觀察記錄
評(píng)論
0/150
提交評(píng)論