C 析構函式 虛析構函式

2021-06-27 06:04:56 字數 1783 閱讀 3762

1.為什麼要定義虛析構函式?

如果有乙個帶有虛函式功能的類,則它需要乙個虛析構函式,原因如下:

1)如果乙個類有虛函式功能,它經常作為乙個基類使用;

2)如果它是乙個基類,它的派生類經常使用new來分配;

3)如果乙個派生類物件使用new來分配,並且通過乙個指向它的基類的指標來控制,那麼它經常通過乙個指向它的基類的指標來刪除它(如果基類沒有虛析構函式,結果將是不確定的,實際發生時,派生類的析構函式永遠不會被呼叫);

基類有虛析構函式的話,最底層的派生類的析構函式最先被呼叫,然後各個基類的析構函式被呼叫。

2.宣告為保護(protected)的析構函式

如果在乙個派生類中定義了基類以外的成員物件,且基類析構函式不是virtual修飾的,那麼當基類指標或引用指向派生類物件並析構(例如自動物件在函式作用域結束時;或者通過delete)時,會呼叫基類的析構函式而導致派生類定義的成員沒有被析構,產生記憶體洩露等問題。

雖然把析構函式定義成virtual的可以解決這個問題,但是當其它成員函式都不是virtual函式時(即基類中沒有虛函式),會在基類和派生類引入vtable,例項引入vptr造成執行時的效能損失。如果確定不需要直接而是只通過派生類物件使用基類,

可以把析構函式定義為protected(這樣會導致基類和派生類外使用自動物件和delete時的錯誤,因為訪問許可權禁止呼叫析構函式),就不會導致以上問題。

3.建構函式、析構函式宣告為私有和保護時的用法

從語法上來講,乙個函式被宣告為protected或者private,那麼這個函式就不能從「外部」直接被呼叫了。

對於protected的函式,子類的「內部」的其他函式可以呼叫之;

而對於private的函式,只能被本類「內部」的其他函式說呼叫;

通常使用的場景如下:

1)如果你不想讓外面的使用者直接構造乙個類(假設這個類的名字為a)的物件,而希望使用者只能構造這個類a的子類,那你就可以將類a的建構函式/析構函式宣告為protected,而將類a的子類的建構函式/析構函式宣告為public。

例如:class a

public:

....

};calss b : public a

....

};a a; // error

b b; // ok

2)如果將建構函式/析構函式宣告為private,那只能這個類的「內部」的函式才能構造這個類的物件了。

例如:class a

~a()

public:

void instance()//類a的內部的乙個函式

};

上面的**是能通過編譯的。上面**裡的instance函式就是類a的內部的乙個函式。instance函式體裡就構建了乙個a的物件。

但是,這個instance函式還是不能夠被外面呼叫的。為什麼呢?

如果要呼叫instance函式,必須有乙個物件被構造出來。但是建構函式被宣告為private的了。外部不能直接構造乙個物件出來。

a aobj; // 編譯通不過

aobj.instance();

但是,如果instance是乙個static靜態函式的話,就可以不需要通過乙個物件,而可以直接被呼叫。

class a

~a()

public:

static a& instance()

void print()

private:

int data;

};a& ra = a::instance();

ra.print();

上面的**其實是設計模式singleton模式的乙個簡單的c++**實現。

C 虛析構函式 純虛析構函式

虛析構函式 析構函式的工作方式是 最底層的派生類 most derived class 的析構函式最先被呼叫,然後呼叫每乙個基類的析構函式。因為在c 中,當乙個派生類物件通過使用乙個基類指標刪除,而這個基類有乙個非虛的析構函式,則結果是未定義的。執行時比較有代表性的後果是物件的派生部分不會被銷毀。然...

C 虛析構函式 純虛析構函式

虛析構函式 析構函式的工作方式是 最底層的派生類 most derived class 的析構函式最先被呼叫,然後呼叫每乙個基類的析構函式。因為在c 中,當乙個派生類物件通過使用乙個基類指標刪除,而這個基類有乙個非虛的析構函式,則結果是未定義的。執行時比較有代表性的後果是物件的派生部分不會被銷毀。然...

C 虛析構函式 純虛析構函式

虛析構函式 析構函式的工作方式是 最底層的派生類 most derived class 的析構函式最先被呼叫,然後呼叫每乙個基類的析構函式。因為在c 中,當乙個派生類物件通過使用乙個基類指標刪除,而這個基類有乙個非虛的析構函式,則結果是未定義的。執行時比較有代表性的後果是物件的派生部分不會被銷毀。然...