C++的類與繼承(二)

01

多繼承


多繼承即一個子類可以有多個父類,它繼承了多個父類的特性。

C++ 類可以從多個類繼承成員,語法如下:

class:1>1>,2>2>,…{};

C++的類與繼承(二)


當上面的代碼被編譯和執行時,它會產生下列結果:

Total area:35Total paint cost: $2450
02構造函數

類的構造函數是類的一種特殊的成員函數,它會在每次創建類的新對象時執行。

構造函數的名稱與類的名稱是完全相同的,並且不會返回任何類型,也不會返回 void,可以有0-n個形參。構造函數可用於為某些成員變量設置初始值。

構造函數具有以下特點:

*構造函數可以重載:只要每個構造函數形參表唯一,同一個類中的構造函數數量不限:

*構造函數自動執行;

*構造函數可以包含一個構造函數初始化列表

* 沒有默認構造函數的類類型的成員,以及 const 或引用類型的成員,必須在初始化列表中完成初始化。

初始化表達式:

Sales_item(const std::string &book, int cnt, double price): isbn(book), units_sold(cnt), revenue(cnt * price) { }

範例:


class ConstRef

{

public:

ConstRef(int ii);

private:

int i;

const int ci;

int &ri;

};

ConstRef::ConstRef(int ii)

{

i = ii; // ok

ci = ii; // error

ri = i; //

}

應該這麼初始化:

ConstRef::ConstRef(int ii): i(ii), ci(i), ri(ii) { }


*不含形參的構造函數就是默認構造函數。

注意:

只有當一個類沒有定義構造函數時,編譯器才會自動生成一個默認構造函數。

一個類只要定義了一個構造函數,編譯器也不會再生成默認構造函數。

03

析構函數



析構函數是構造函數的互補:當對象超出作用域或動態分配的對象被刪除時,將自動應用析構函數。

析構函數可用於釋放構造對象時或在對象的生命期中所獲取的資源。

析構函數的名稱與類的名稱是完全相同的,只是在前面加了個波浪號(~)作為前綴,它不會返回任何值,也不能帶有任何參數。析構函數有助於在跳出程序(比如關閉文件、釋放內存等)前釋放資源。

C++的類與繼承(二)

當上面的代碼被編譯和執行時,它會產生下列結果:

Objectis being createdLength of line :6Objectis being deleted

構造函數的用途之一是自動獲取資源;與之相對的是,析構函數的用途之一是回收資源。除此之外,析構函數可以執行任意類設計者希望在該類對象的使用完畢之後執行的操作。
(1) 何時調用析構函數

  • 撤銷(銷燬)類對象時會自動調用析構函數。

  • 變量(類對象)在超出作用域時應該自動撤銷(銷燬)。

  • 動態分配的對象(new A)只有在指向該對象的指針被刪除時才撤銷(銷燬)。

  • 撤銷(銷燬)一個容器(不管是標準庫容器還是內置數組)時,也會運行容器中的類類型元素的析構函數(容器中的元素總是從後往前撤銷

    )。

(2)何時編寫顯式析構函數
如果類需要定義析構函數,則它也需要定義賦值操作符和複製構造函數,這個規則常稱為三法則:如果類需要析構函數,則需要所有這三個複製控制成員。
(3)合成析構函數

合成析構函數按對象創建時的逆序撤銷每個非 static 成員,因此,它按成員在類中聲明次序的逆序撤銷成員。

對於每個類類型的成員,合成析構函數調用該成員的析構函數來撤銷對象。

合成析構函數並不刪除指針成員所指向的對象。 所以,如果有指針成員,一定要定義自己的析構函數來刪除指針。

析構函數與複製構造函數或賦值操作符之間的一個重要區別:即使我們編寫了自己的析構函數,合成析構函數仍然運行。










分享到:


相關文章: