(一四三)类设计回顾
編譯器自動(dòng)生成的特殊成員函數(shù):
默認(rèn)構(gòu)造函數(shù):
當(dāng)構(gòu)造函數(shù)無(wú)參數(shù)、或所有參數(shù)都有默認(rèn)值時(shí)(二者不能同時(shí)存在),則是默認(rèn)構(gòu)造函數(shù)。
?
自動(dòng)生成的默認(rèn)構(gòu)造函數(shù),將調(diào)用基類(lèi)的默認(rèn)構(gòu)造函數(shù);如果類(lèi)的數(shù)據(jù)成員是另一個(gè)類(lèi)的對(duì)象,那么這個(gè)數(shù)據(jù)成員在生成的時(shí)候,也會(huì)調(diào)用其默認(rèn)構(gòu)造函數(shù)。
?
假如定義了某個(gè)構(gòu)造函數(shù),那么編譯器將不會(huì)定義默認(rèn)構(gòu)造函數(shù)。
?
假如類(lèi)數(shù)據(jù)成員有指針,應(yīng)該在默認(rèn)構(gòu)造函數(shù)中正確為其分配內(nèi)存地址。
?
?
復(fù)制構(gòu)造函數(shù):
原型:類(lèi)名(const?類(lèi)名&?);
使用復(fù)制構(gòu)造函數(shù)的四種情況(關(guān)鍵是在聲明一個(gè)類(lèi)并初始化時(shí)):
①將新對(duì)象初始化為一個(gè)同類(lèi)對(duì)象(如Man?a=b;?Man是類(lèi)名,下同);
②按值將對(duì)象傳遞給函數(shù)(如void?show(Man?a));
③函數(shù)按值返回對(duì)象(如Man?show(););
④編譯器生成臨時(shí)對(duì)象(臨時(shí)對(duì)象通常在以下情況產(chǎn)生:①類(lèi)型轉(zhuǎn)換;②按值返回;③按值傳遞;④對(duì)象定義);
?
具體情況:
①類(lèi)里沒(méi)有聲明復(fù)制構(gòu)造函數(shù),也沒(méi)用使用——編譯器提供復(fù)制構(gòu)造函數(shù)原型,但不提供定義;
?
②類(lèi)中沒(méi)有聲明,但是使用了——編譯器提供復(fù)制構(gòu)造函數(shù)的原型和定義(數(shù)據(jù)成員按值傳遞);
?
③類(lèi)中聲明了,使用類(lèi)提供的復(fù)制構(gòu)造函數(shù)。
?
?
賦值運(yùn)算符:
在聲明類(lèi)的時(shí)候,調(diào)用構(gòu)造函數(shù)或復(fù)制構(gòu)造函數(shù)。
而當(dāng)類(lèi)對(duì)象被聲明之后,將一個(gè)類(lèi)對(duì)象賦值給另一個(gè)類(lèi)對(duì)象時(shí),才使用賦值運(yùn)算符。
原型:類(lèi)名&?operator=(const?類(lèi)名&?);
?
①默認(rèn)情況下,將使用逐成員按值傳遞;
?
②假如數(shù)據(jù)成員是另一個(gè)類(lèi)對(duì)象,則在按值傳遞的時(shí)候,調(diào)用該類(lèi)的賦值運(yùn)算符(如果該類(lèi)沒(méi)有,則使用該類(lèi)的默認(rèn)賦值運(yùn)算符);
?
③對(duì)于指針(由new分配內(nèi)存)作為數(shù)據(jù)成員時(shí),由于構(gòu)造函數(shù)需要顯式聲明,同樣,賦值運(yùn)算符也需要顯式聲明以處理其情況;
?
如果要將另一個(gè)類(lèi)型賦值給類(lèi)對(duì)象,方法①是定義該類(lèi)型作為賦值運(yùn)算符的參數(shù);方法②是使用轉(zhuǎn)換函數(shù)(之構(gòu)造函數(shù),將其他類(lèi)型轉(zhuǎn)換為臨時(shí)類(lèi)對(duì)象,然后通過(guò)臨時(shí)類(lèi)對(duì)象賦值給類(lèi)對(duì)象);
?
?
?
其他類(lèi)方法:
構(gòu)造函數(shù):
特點(diǎn)是聲明一個(gè)新對(duì)象時(shí)調(diào)用(視情況調(diào)用默認(rèn)構(gòu)造函數(shù)、構(gòu)造函數(shù)、或者是復(fù)制構(gòu)造函數(shù))。
?
構(gòu)造函數(shù)不被派生類(lèi)繼承,但派生類(lèi)的構(gòu)造函數(shù)會(huì)默認(rèn)調(diào)用基類(lèi)的構(gòu)造函數(shù)。
?
如果類(lèi)的數(shù)據(jù)成員使用動(dòng)態(tài)內(nèi)存,那么應(yīng)顯式的聲明構(gòu)造函數(shù)、復(fù)制構(gòu)造函數(shù)、賦值運(yùn)算符和析構(gòu)函數(shù)。
?
?
析構(gòu)函數(shù):
①基類(lèi)的析構(gòu)函數(shù)應(yīng)該定義為虛的,即使沒(méi)有任何內(nèi)容,也至少應(yīng)該有一個(gè)虛的析構(gòu)函數(shù)。
?
②如果構(gòu)造函數(shù)使用new來(lái)分配動(dòng)態(tài)內(nèi)存給數(shù)據(jù)成員,那么析構(gòu)函數(shù)應(yīng)該使用對(duì)應(yīng)的delete來(lái)釋放內(nèi)存。
?
③需要顯式的使用析構(gòu)函數(shù)的情況很少,使用new定位運(yùn)算符創(chuàng)建的類(lèi)對(duì)象,是少數(shù)幾種需要顯式的調(diào)用析構(gòu)函數(shù)的情況之一(因?yàn)椴荒芡ㄟ^(guò)直接delete類(lèi)對(duì)象的方式,來(lái)調(diào)用析構(gòu)函數(shù))。
?
?
?
轉(zhuǎn)換:
使用一個(gè)參數(shù)就可以調(diào)用的構(gòu)造函數(shù),定義了從參數(shù)類(lèi)型到類(lèi)類(lèi)型的轉(zhuǎn)換。
例如將一個(gè)int類(lèi)型作為類(lèi)構(gòu)造函數(shù)的參數(shù),那么這個(gè)類(lèi)對(duì)象可以等于int類(lèi)型(利用構(gòu)造函數(shù),然后調(diào)用賦值運(yùn)算符)。
?
如果需要禁止這種情況發(fā)生,可以在構(gòu)造函數(shù)前面加上關(guān)鍵字explicit,來(lái)禁止隱式轉(zhuǎn)換,于是只有顯式的調(diào)用對(duì)應(yīng)的構(gòu)造函數(shù)時(shí),才能進(jìn)行轉(zhuǎn)換。
?
將類(lèi)對(duì)象轉(zhuǎn)換為其他類(lèi)型的轉(zhuǎn)換函數(shù),可以是沒(méi)有參數(shù)的類(lèi)成員函數(shù)(例如operator?int());也可以是返回類(lèi)型被聲明為目標(biāo)類(lèi)型的類(lèi)成員函數(shù)(不懂)。
?
?
?
按值傳遞、按引用傳遞,返回對(duì)象和返回引用:
使用引用的好處:
①節(jié)省內(nèi)存開(kāi)支(不需要?jiǎng)?chuàng)建臨時(shí)對(duì)象);
?
②對(duì)于指針,如返回臨時(shí)對(duì)象的話(huà),應(yīng)顯式聲明復(fù)制構(gòu)造函數(shù),但返回引用就不用;
?
缺點(diǎn):
①不能對(duì)函數(shù)內(nèi)部創(chuàng)造的對(duì)象返回引用(因?yàn)殡x開(kāi)函數(shù)塊時(shí)該引用的原型會(huì)被銷(xiāo)毀);
?
通常來(lái)說(shuō),如果是函數(shù)內(nèi)部創(chuàng)造的對(duì)象,然后返回它,就應(yīng)該使用返回對(duì)象而非返回引用。否則,應(yīng)盡量使用返回引用(如果要求其不能成為左值,則加上關(guān)鍵字const);
?
?
?
使用const:
作用:
①可以確保類(lèi)方法不修改對(duì)象的數(shù)據(jù)成員(在參數(shù)列表的括號(hào)后加const);
?
②確保類(lèi)方法不修改調(diào)用的參數(shù)(在參數(shù)類(lèi)型名前加const);
?
③確保類(lèi)方法的返回值不被修改(在返回值的類(lèi)型名前加cosnt);
?
?
?
?
公有繼承的考慮因素:
is-a關(guān)系:
要遵循is-a關(guān)系,如果派生類(lèi)不是一種特殊的基類(lèi),則不要使用公有派生。(不懂)
感覺(jué)大概意思是說(shuō),一個(gè)類(lèi)作為基類(lèi)還是作為另一個(gè)類(lèi)的成員對(duì)象,要看情況。有些時(shí)候適合做基類(lèi)(例如派生類(lèi)是基類(lèi)的一種),有些時(shí)候適合做成員對(duì)象(例如派生類(lèi)是基類(lèi)的一部分)。
?
可以創(chuàng)建具有純虛函數(shù)的抽象基類(lèi),然后派生出其他類(lèi)。
?
基類(lèi)的指針、引用可以指向派生類(lèi)對(duì)象,但不能反過(guò)來(lái)。
?
?
?
什么不能被繼承:
①構(gòu)造函數(shù):但在派生類(lèi)構(gòu)造函數(shù)時(shí)會(huì)自動(dòng)調(diào)用基類(lèi)的構(gòu)造函數(shù);
?
②析構(gòu)函數(shù):派生類(lèi)析構(gòu)函數(shù)也會(huì)自動(dòng)調(diào)用基類(lèi)的析構(gòu)函數(shù);
?
③賦值運(yùn)算符:視情況而定,有時(shí)候可以使用默認(rèn)的,有時(shí)候需要自定義,并顯式調(diào)用基類(lèi)的賦值運(yùn)算符函數(shù)(基類(lèi)名::operator=(參數(shù)對(duì)象))。
?
?
賦值運(yùn)算符:
①默認(rèn)賦值運(yùn)算符版本,將逐成員按值傳遞;
?
②派生類(lèi)的賦值運(yùn)算符如果是默認(rèn)版本,將對(duì)基類(lèi)部分調(diào)用基類(lèi)的賦值運(yùn)算符,對(duì)派生類(lèi)新增數(shù)據(jù)成員按值傳遞;
?
③如果自定義派生類(lèi)賦值運(yùn)算符,那么需要顯式的聲明基類(lèi)的賦值運(yùn)算符以復(fù)制基類(lèi)的部分;
?
④遇見(jiàn)new來(lái)分配內(nèi)存,應(yīng)自定義賦值運(yùn)算符;
?
⑤默認(rèn)情況下,派生類(lèi)對(duì)象賦值給基類(lèi)對(duì)象,相當(dāng)于將派生類(lèi)對(duì)象強(qiáng)制轉(zhuǎn)換為基類(lèi)并賦值(相反則不行,只能調(diào)用參數(shù)合適的構(gòu)造函數(shù),或參數(shù)合適的賦值運(yùn)算符)。
?
?
?
私有成員和保護(hù)成員:
對(duì)于派生類(lèi)而言,保護(hù)成員類(lèi)似公有成員;
對(duì)于外界而言,保護(hù)成員類(lèi)似私有成員。
?
?
?
虛方法:
格式是函數(shù)原型(函數(shù)定義不需要)加關(guān)鍵字virtual。
①基類(lèi)的析構(gòu)函數(shù)需要虛方法;
?
②對(duì)于派生類(lèi)需要重新定義的方法,基類(lèi)使用虛方法(派生類(lèi)可以不用,但用的話(huà)可以明確表示基類(lèi)該方法也是虛的);
?
③使用虛方法時(shí),受傳遞的對(duì)象所影響(按引用、指針傳遞,和按值傳遞的結(jié)果是不一樣的);
?
?
析構(gòu)函數(shù):
公有繼承的析構(gòu)函數(shù)應(yīng)該是虛的。
?
?
?
友元函數(shù):
派生類(lèi)不繼承友元函數(shù),但可以顯式的調(diào)用友元函數(shù)。方法是?類(lèi)名::基類(lèi)友元函數(shù)?。或者是使用強(qiáng)制類(lèi)型轉(zhuǎn)換。
?
?
?
關(guān)于使用基類(lèi)方法的說(shuō)明:
①某方法如果派生類(lèi)沒(méi)有重新定義,則使用基類(lèi)的;
?
②派生類(lèi)構(gòu)造函數(shù)自動(dòng)調(diào)用基類(lèi)的,默認(rèn)調(diào)用默認(rèn)構(gòu)造函數(shù),除非更改聲明調(diào)用的構(gòu)造函數(shù)(例如原本是調(diào)用默認(rèn)構(gòu)造函數(shù)的,1個(gè)參數(shù)。改用另一個(gè)構(gòu)造函數(shù),2個(gè)參數(shù)的);
?
③一般情況下,派生類(lèi)復(fù)制構(gòu)造函數(shù)會(huì)自動(dòng)使用基類(lèi)的復(fù)制構(gòu)造函數(shù),除非自己顯式的在派生類(lèi)復(fù)制構(gòu)造函數(shù)使用其他構(gòu)造函數(shù);
?
④派生類(lèi)的方法中,可以通過(guò)作用域解析運(yùn)算符(雙冒號(hào))顯式的調(diào)用基類(lèi)的方法(前提不是私有的);
?
?
?
其他(附表):
總結(jié)
以上是生活随笔為你收集整理的(一四三)类设计回顾的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 七猫免费阅读小说怎样用(如何看待七猫中文
- 下一篇: 邮储银行APP如何修改登陆帐号