C 類析構函式的顯示呼叫和隱式呼叫

2021-09-25 16:30:11 字數 1209 閱讀 9992

參考與致謝

為了理解這個問題,我們必須首先弄明白「堆」和「棧」的概念。

堆區(heap) —— 一般由程式設計師分配釋放, 若程式設計師不釋放,程式結束時可能由os** 。注意它與資料結構中的堆是兩回事,分配方式倒是類似於鍊錶。

棧區(stack)—— 由編譯器自動分配釋放 ,存放函式的引數值,區域性變數的值等。其操作方式類似於資料結構中的棧。

我們構造物件,往往都是在一段語句體中,比如函式,判斷,迴圈,還有就直接被一對「{}」包含的語句體,這就是有時候為了使得類被析構掉,只使用一對{}來欺騙程式,使得析構函式被呼叫。這個物件在語句體中被建立,在語句體結束的時候被銷毀。問題就在於,這樣的物件在生命週期中是存在於棧上的。也就是說,如何管理,是系統完成而程式設計師不能控制的。所以,即使我們呼叫了析構,在物件生命週期結束後,系統仍然會再呼叫一次析構函式,將其在棧上銷毀,實現真正的析構。總之,隱式呼叫析構函式的前提是類的建立是在棧上,而不是堆上。

所以,如果我們在析構函式中有清除堆資料的語句,呼叫兩次意味著第二次會試圖清理已經被清理過了的,根本不再存在的資料!這是件會導致執行時錯誤的問題,並且在編譯的時候不會告訴你。

1.顯式呼叫的時候,析構函式相當於的乙個普通的成員函式。

2.編譯器隱式呼叫析構函式,如分配了對記憶體,顯式呼叫析構的話引起重複釋放堆記憶體的異常。

3.把乙個物件看作占用了部分棧記憶體,占用了部分堆記憶體(如果申請了的話),這樣便於理解這個問題。

4.系統隱式呼叫析構函式的時候,會加入釋放棧記憶體的動作(而堆記憶體則由使用者手工的釋放)。

5.使用者顯式呼叫析構函式的時候,只是單純執行析構函式內的語句,不會釋放棧記憶體,摧毀物件。

如果物件被建立在堆上,系統就不會自動呼叫。乙個常見的例子是new…delete組合。但是好在呼叫delete的時候,析構函式還是被自動呼叫了。很罕見的例外在於使用布局new的時候,在delete設定的快取之前,需要顯式呼叫的析構函式,這實在是很少見的情況。

建立乙個類指標

pitch *thee3 = null;

建立函式的返回值是類指標,pitch *thee = new pitch(); thee就是函式的返回值,由於類指標在函式內用new來建立,說明thee是被建立在了堆上,thee3生命週期結束後,析構函式不被隱式呼叫,需要程式設計師自己釋放,此時有2個方法可以解決:1.顯示呼叫析構函式thee3->~pitch(); 2.使用delete thee3;讓delete函式去呼叫析構函式。

本文參考且大部分拷貝於

在此向原文作者致謝~

關於建構函式和析構函式的隱式呼叫

一 首先是最基本的呼叫 class test public test cout default constructor default constructor default destructor 二 在形參值傳遞時的呼叫 class test public test cout default co...

C 顯示呼叫建構函式和析構函式

建構函式和析構函式可不可以顯示呼叫 class a a void main 此時的輸出結果是 a constructor a constructor 顯示呼叫建構函式的結果。a destrucotr 顯示呼叫析構函式的結果,此時物件並沒有銷毀。a destructor 物件銷毀時自動呼叫析構函式。總...

C 顯示呼叫建構函式和析構函式

類在new的時候其實做了兩件事情 1 呼叫malloc分配所需的記憶體 實際上是呼叫operator new 2 呼叫建構函式 類在delete的時候其實也做了兩件事 1 呼叫析構函式 2 呼叫free釋放記憶體 實際上是呼叫operator delete 直接通過 類名 建構函式或析構函式clas...