今天用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運算子動態地建立了乙個物件 必須顯式用 ...