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