析構函式 private virtual的作用

2021-06-16 14:36:20 字數 2169 閱讀 3744

類中「私有」許可權的含義就是:私有成員只能在類域內被訪問,不能在類域外進行訪問。   

把析構函式定義為私有的,就阻止了使用者在類域外對析構函式的使用。這表現在如下兩個方面:   

1.  禁止使用者對此型別的變數進行定義,即禁止在棧記憶體空間內建立此型別的物件。要建立物件,只能用   new   在堆上進行。   

2.  禁止使用者在程式中使用   delete   刪除此型別物件。物件的刪除只能在類內實現,也就是說只有類的實現者才有可能實現對物件的   delete,使用者不能隨便刪除物件。如果使用者想刪除物件的話,只能按照類的實現者提供的方法進行。  

《more effective c++》

條款27: 要求或禁止基於堆的物件

有時你想這樣管理某些物件,要讓某種型別的物件能夠自我銷毀,也就是能夠「delete this」。很明顯這種管理方式需要此型別物件被分配在堆中。而其它一些時候你想獲得一種保障:「不在堆中分配物件,從而保證某種型別的類不會發生記憶體洩漏。」如果你在嵌入式系統上工作,就有可能遇到這種情況,發生在嵌入式系統上的記憶體洩漏是極其嚴重的,其堆空間是非常珍貴的。有沒有可能編寫出**來要求或禁止在基於堆的物件(heap-based object)呢?通常是可以的,不過這種**也會把「在堆中」的概念搞得比你腦海中所想的要模糊。

要求基於堆的物件

讓我們先從必須在堆中建立物件開始說起。為了執行這種限制,你必須找到一種方法禁止以呼叫「new」以外的其它手段建立物件。這很容易做到。非堆物件(non-heap object)在定義它的地方被自動構造,在生存時間結束時自動被釋放,所以只要禁止使用隱式的建構函式和析構函式,就可以實現這種限制。

把這些呼叫變得不合法的一種最直接的方法是把建構函式和析構函式宣告為private。這樣做***太大。沒有理由讓這兩個函式都是private。最好讓析構函式成為private,讓建構函式成為public。處理過程與條款26相似,你可以引進乙個專用的偽析構函式,用來訪問真正的析構函式。客戶端呼叫偽析構函式釋放他們建立的物件。

析構函式

virtual

與非virtual

區別

作為通常的原則,如果乙個類定義了虛函式,那麼它的析構函式就應當是virtual的。因為定義了虛函式則隱含著:這個類會被繼承,並且會通過基類的指標指向子類物件,從而得到多型性。   這個類可能會被繼承,並且會通過基類的指標指向子類物件」,因此基類的析構函式是否為虛將決定子類的物件是否被析構

示例**:

#include struct a

};struct b: public a

};void main()

如果 a的析構函式不是virtual的,那麼此時就不是先呼叫b的析構函式再呼叫a的析構函式。 

output:

~a();  

如果a   的析構函式為virtual,則先~b(),再~a()   

output:

~b();

~a();

類如果會被派生的話,析構函式一般都應該定義為virtual的,主要不是防止記憶體洩露,而是為了正確的析構。如果是個封閉類(即不再被派生),就不要定義為virtual的。虛函式畢竟耗費較大的。

不用virtual 的幾種情況:

1、作為非公有基類。僅作為   private   base   class   使用的  class   不需要使用虛擬析構函式   

2、不作為介面使用的基類。   

3.   如果你可以保證這個類不被public繼承(private/protected繼承的話,在非friend函式/類中就無法用基類指標指向派生類了)   

4.   如果它的所有派生類(包括派生類的派生類)的析構函式都是trivial的(這裡的trivial指的是在程式設計師的層次什麼事也不做)   

5.   如果不需要用基類的指標指向派生類的物件   

在這五種情況下,不把析構函式宣告為virtual都是可以的,何況效率會高一些——但前提是你得保證前提的成立——不過這些保證常常是很難100%的:誰能保證別人在派生你的類的時候,析構函式是trivial的,或者別人不用你提供的基類的指標指向派生類物件?這些常常是很難得到保證的。  

宣告基類的析構函式為virtual並非總是為了防止memory   leak   另外這也只是作為一般的原則(基類中有虛函式則把其析構函式宣告為virtual)。如果你的析構函式什麼事也不作,從效果上來說,不宣告為virtual也無妨

C 析構函式 虛析構函式

1.為什麼要定義虛析構函式?如果有乙個帶有虛函式功能的類,則它需要乙個虛析構函式,原因如下 1 如果乙個類有虛函式功能,它經常作為乙個基類使用 2 如果它是乙個基類,它的派生類經常使用new來分配 3 如果乙個派生類物件使用new來分配,並且通過乙個指向它的基類的指標來控制,那麼它經常通過乙個指向它...

建構函式 析構函式 虛析構函式

說析構函式之前,先說下建構函式。建構函式用來完成對物件的一系列初始化操作,主要作用有 1.給建立的物件建立乙個識別符號 2.為物件資料成員開闢記憶體空間 3.完成物件資料成員的初始化 當並未顯示的定義建構函式時,會生成乙個預設的建構函式,預設建構函式不能完成物件資料成員的初始化,只能給物件建立一識別...

C 析構函式和虛析構函式。

析構函式如果不是虛的話,基類的析構函式將不會被呼叫。多型時,也就是派生類被基類指標所指,或者被基類別名 虛析構函式,被呼叫時,其自身的析構函式和基類的析構函式都將會被呼叫。非虛的時候,不進行多型,只有基類的會被呼叫。純虛析構函式 定義的時候除了加 0 還需要給出函式的實現。因為當遞迴的呼叫析構函式時...