(一四三)類設計回顧

2021-09-23 22:56:22 字數 3961 閱讀 3371

編譯器自動生成的特殊成員函式:

預設建構函式:

當建構函式無引數、或所有引數都有預設值時(二者不能同時存在),則是預設建構函式。

自動生成的預設建構函式,將呼叫基類的預設建構函式;如果類的資料成員是另乙個類的物件,那麼這個資料成員在生成的時候,也會呼叫其預設建構函式。

假如定義了某個建構函式,那麼編譯器將不會定義預設建構函式。

假如類資料成員有指標,應該在預設建構函式中正確為其分配記憶體位址。

複製建構函式:

原型:類名

(const 

類名& );

使用複製建構函式的四種情況(關鍵是在宣告乙個類並初始化時):

①將新物件初始化為乙個同類物件(如man a=b; man

是類名,下同);

②按值將物件傳遞給函式(如void show(man a));

③函式按值返回物件(如man show(););

④編譯器生成臨時物件(臨時物件通常在以下情況產生:①型別轉換;②按值返回;③按值傳遞;④物件定義);

具體情況:

①類裡沒有宣告複製建構函式,也沒用使用——編譯器提供複製建構函式原型,但不提供定義;

②類中沒有宣告,但是使用了——編譯器提供複製建構函式的原型和定義(資料成員按值傳遞);

③類中宣告了,使用類提供的複製建構函式。

賦值運算子:

在宣告類的時候,呼叫建構函式或複製建構函式。

而當類物件被宣告之後,將乙個類物件賦值給另乙個類物件時,才使用賦值運算子。

原型:類名& 

operator=(const 

類名&);

①預設情況下,將使用逐成員按值傳遞;

②假如資料成員是另乙個類物件,則在按值傳遞的時候,呼叫該類的賦值運算子(如果該類沒有,則使用該類的預設賦值運算子);

③對於指標(由new

分配記憶體)作為資料成員時,由於建構函式需要顯式宣告,同樣,賦值運算子也需要顯式宣告以處理其情況;

如果要將另乙個型別賦值給類物件,方法①是定義該型別作為賦值運算子的引數;方法②是使用轉換函式(之建構函式,將其他型別轉換為臨時類物件,然後通過臨時類物件賦值給類物件);

其他類方法:

建構函式:

特點是宣告乙個新物件時呼叫(視情況呼叫預設建構函式、建構函式、或者是複製建構函式)。

建構函式不被派生類繼承,但派生類的建構函式會預設呼叫基類的建構函式。

如果類的資料成員使用動態記憶體,那麼應顯式的宣告建構函式、複製建構函式、賦值運算子和析構函式。

析構函式:

①基類的析構函式應該定義為虛的,即使沒有任何內容,也至少應該有乙個虛的析構函式。

②如果建構函式使用new

來分配動態記憶體給資料成員,那麼析構函式應該使用對應的

delete

來釋放記憶體。

③需要顯式的使用析構函式的情況很少,使用new

定位運算子建立的類物件,是少數幾種需要顯式的呼叫析構函式的情況之一(因為不能通過直接

delete

類物件的方式,來呼叫析構函式)。

轉換:

使用乙個引數就可以呼叫的建構函式,定義了從引數型別到類型別的轉換。

例如將乙個int

型別作為類建構函式的引數,那麼這個類物件可以等於

int型別(利用建構函式,然後呼叫賦值運算子)。

如果需要禁止這種情況發生,可以在建構函式前面加上關鍵字explicit,來禁止隱式轉換,於是只有顯式的呼叫對應的建構函式時,才能進行轉換。

將類物件轉換為其他型別的轉換函式,可以是沒有引數的類成員函式(例如operator int());也可以是返回型別被宣告為目標型別的類成員函式(不懂)。

按值傳遞、按引用傳遞,返回物件和返回引用:

使用引用的好處:

①節省記憶體開支(不需要建立臨時物件);

②對於指標,如返回臨時物件的話,應顯式宣告複製建構函式,但返回引用就不用;

缺點:①不能對函式內部創造的物件返回引用(因為離開函式塊時該引用的原型會被銷毀);

通常來說,如果是函式內部創造的物件,然後返回它,就應該使用返回物件而非返回引用。否則,應盡量使用返回引用(如果要求其不能成為左值,則加上關鍵字const);

使用const

:作用:①可以確保類方法不修改物件的資料成員(在引數列表的括號後加const);

②確保類方法不修改呼叫的引數(在引數型別名前加const);

③確保類方法的返回值不被修改(在返回值的型別名前加cosnt);

公有繼承的考慮因素:

is-a關係:

要遵循is-a

關係,如果派生類不是一種特殊的基類,則不要使用公有派生。

(不懂)

感覺大概意思是說,乙個類作為基類還是作為另乙個類的成員物件,要看情況。有些時候適合做基類(例如派生類是基類的一種),有些時候適合做成員物件(例如派生類是基類的一部分)。

可以建立具有純虛函式的抽象基類,然後派生出其他類。

基類的指標、引用可以指向派生類物件,但不能反過來。

什麼不能被繼承:

①建構函式:但在派生類建構函式時會自動呼叫基類的建構函式;

②析構函式:派生類析構函式也會自動呼叫基類的析構函式;

③賦值運算子:視情況而定,有時候可以使用預設的,有時候需要自定義,並顯式呼叫基類的賦值運算子函式(基類名

::operator=(

引數物件

))。賦值運算子:

①預設賦值運算子版本,將逐成員按值傳遞;

②派生類的賦值運算子如果是預設版本,將對基類部分呼叫基類的賦值運算子,對派生類新增資料成員按值傳遞;

③如果自定義派生類賦值運算子,那麼需要顯式的宣告基類的賦值運算子以複製基類的部分;

④遇見new

來分配記憶體,應自定義賦值運算子;

⑤預設情況下,派生類物件賦值給基類物件,相當於將派生類物件強制轉換為基類並賦值(相反則不行,只能呼叫引數合適的建構函式,或引數合適的賦值運算子)。

私有成員和保護成員:

對於派生類而言,保護成員類似公有成員;

對於外界而言,保護成員類似私有成員。

虛方法:

格式是函式原型(函式定義不需要)加關鍵字virtual。

①基類的析構函式需要虛方法;

②對於派生類需要重新定義的方法,基類使用虛方法(派生類可以不用,但用的話可以明確表示基類該方法也是虛的);

③使用虛方法時,受傳遞的物件所影響(按引用、指標傳遞,和按值傳遞的結果是不一樣的);

析構函式:

公有繼承的析構函式應該是虛的。

友元函式:

派生類不繼承友元函式,但可以顯式的調用友元函式。方法是 類名

::基類友元函式 。或者是使用強制型別轉換。

關於使用基類方法的說明:

①某方法如果派生類沒有重新定義,則使用基類的;

②派生類建構函式自動呼叫基類的,預設呼叫預設建構函式,除非更改宣告呼叫的建構函式(例如原本是呼叫預設建構函式的,1

個引數。改用另乙個建構函式,

2個引數的);

③一般情況下,派生類複製建構函式會自動使用基類的複製建構函式,除非自己顯式的在派生類複製建構函式使用其他建構函式;

④派生類的方法中,可以通過作用域解析運算子(雙冒號)顯式的呼叫基類的方法(前提不是私有的);

其他(附表):

類設計回顧

1.編譯器生成的成員函式 1 預設建構函式 沒有引數,或所有引數都有預設值 確保物件總能被正確地初始化 star rigel star pleiades 6 功能 1 呼叫基類的預設建構函式以及呼叫本身是物件的成員所屬類的預設建構函式 2 如果派生類建構函式的成員初始化列表中沒有顯式呼叫基類建構函式...

C 類繼承7 類設計回顧

編譯器會自動生成一些公有的成員函式 特殊成員函式。1 預設建構函式 提供建構函式的動機之一是確保物件總能被正確地初始化。如果類包含指標成員,則必須初始化這些成員。最好提供乙個顯式預設建構函式,將所有的類資料成員都初始化為合理的值。如果定義了某種建構函式,編譯器將不會定義預設建構函式。如果沒有定義任何...

三類MySQL MySQL常用的三類函式

經常編寫程式或者使用資料庫的同學一定體會到函式的重要性,豐富的函式往往能使使用者的工作事半功倍。函式能幫助使用者做很多事情,比如說字串的處理 數值的運算 日期的運算等,在這方面mysql提供了多種內建函式幫助開發人員編寫簡單快捷的sql語句,其中常用的函式有字串函式 日期函式和數值函式。1 字串函式...