關於C 手動呼叫析構函式的理解

2021-09-01 09:18:03 字數 1712 閱讀 4848

今天用c++改寫jept_json的時候遇到了乙個問題。

首先,在lept_json中,在lept_value中定義了乙個聯合

struct lept_value s;                   /* string: null-terminated string, string length */

double n; /* number */

}u;lept_type type;

};

一開始c++中也想這麼寫,想想不用自己建棧了美滋滋啊

union ;
還順便用了下匿名union,以後訪問再也不用v->u.n了。

然後編譯器就報錯啦!

建構函式是已刪除的函式?

回憶了一下c++ primer裡講的,這裡也沒有成員沒有預設建構函式呀?

想了下,這個問題也只可能是union引起的。查了查果然是,由於union裡有類型別,因此編譯器就懵逼了,不知道呼叫誰的建構函式。

自己手動新增建構函式和析構函式吧。

建構函式容易解決,在構造階段,直接吧type置為type_null就可以了。

略麻煩的是析構函式。以前從來沒有自己手動呼叫過析構函式,這裡明顯是要根據型別來呼叫析構函式啊。

踩個坑,可能理解的也沒有很透徹

參考別人的,寫了個測試類。

class testdes 

~testdes()

string s = "sssssss";

vectorivec;

int i = 0;

//int *pi;

};

testdes t;

cout << t.s << endl;

cout << t.i << endl;

for (auto i : t.ivec)

cout << i << " ";

cout << endl;

//cout << *t.pi << endl;

t.~testdes();

cout << t.s << endl;

cout << t.i << endl;

for (auto i : t.ivec)

cout << i << " ";

cout << endl;

cout << t.ivec.size() << endl;

執行結果:

在上面的**狀態下,當類內沒有int* pi,也就是沒有堆區資料的時候,儘管析構函式被呼叫了兩次,但是沒有什麼問題。類內的string和vector在第一次呼叫析構函式後資料就被清理了,但是還在棧區占有空間。int沒有收到影響,可以第二次呼叫。

但是如果去掉注釋,第二次delete pi肯定就會報錯了,因為不能把一塊空間釋放兩次。(其實可以delete完了pi=nullptr)。

所以,可以根據型別判斷,呼叫union的對應型別的析構函式。

關於c 顯示呼叫析構函式的陷阱

現在在寫乙個專案,需要用到多叉樹儲存結構,但是在某個時候,我需要銷毀這棵樹,這意味著如果我新建了乙個樹物件,我很可能在某處希望將這個物件的宣告週期終結,自然會想到顯示呼叫析構函式,但是就扯出來這麼大個陷阱。在了解為什麼不要輕易顯示呼叫析構函式之前,先來看看預備知識。為了理解這個問題,我們必須首先弄明...

c 析構函式呼叫解析

說明 系統只會自動釋放棧內空間,而堆內空間需要使用者自己維護。c 中,除了new來的空間存放在堆內,其他均存放在棧中。當單純的建立物件的時候,物件存放在棧中,此時在程式塊的 後面,系統會自動呼叫析構函式,釋放掉棧空間。但是,如果建立了指向new來的一塊空間的指標的時候,如果在沒有顯示釋放掉new到的...

析構函式的呼叫

看到這樣乙個例子 class b private int data public b cout default constructor destructed by parameter 5 destructed 那麼都有哪些情況會呼叫析構函式呢?1.當用 new運算子動態地建立了乙個物件 必須顯式用 ...