C++ POD与结构体声明
上面的結構休定義有問題嗎?理論上說沒有,但在某些情況下就有問題了。如下用法:
如果這樣用的話,在Debug下運行沒有問題,但在Release下運行,就會在push_back處Crash。這是為什么呢?這就引出下面要講的POD了。
?
什么是POD
?
POD(Plain Old Data)指的是能夠像C語言中的結構體那樣進行處理的一種數據類型,比如能夠使用memcpy()來復制內存,使用memset()進行初始化等。
在C++ 98標準中,POD實際上是受限于結構體定義中的語言特性而定義的。
在C++0x中,POD被定義為可以簡簡單單復制的,類型普通的,并且擁有可以應對多種POD原先就能支持的操作的標準變量地址布局(?)。POD的定義和以前差不多:
1)如果你所有的成員變量和基類都是POD,那么這個類型就是POD。
2)POD應當滿足以下要求,
?????a)沒有虛函數
?????b)沒有虛基類
?????c)沒有引用
?????d)沒有多重訪問
新標準對POD最大的影響就是,對于擁有不會影響數據分配布局的構造函數的數據結構,也可以算作是POD。
關于POD詳細信息,請參考官方文檔:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2294.html
?
Crash原因分析?
?
回到最上面舉的那個例子,結構體初始化時,首先會調用它自動生成的默認構造函數,同時也會調用vector<wstring>的構造函數為pstr成員生成一塊內存。然后我們都知道,使用結構體一般都會用memset 或 ZeroMemory函數來把結構體清成0,那么當我們調用ZeroMemory后,之前為pstr生成的內存就變成了0,這樣當在后面再訪問這個成員時,就會導致Crash。
所以一般情況下在結構體中不要定義一些復雜的數據類型,如果無法避免,就聲明這種類型的指針,因為指針肯定是一個POD的數據。
?
解決方法
?
1)上面的那種方法可以把pstr換成指針類型,也就是vector<wstring>* 在調用ZeroMemory后,再對這個變量分配內存。
2)為這個結構體寫構造函數,在這個構造函數里面進行初始化,在使用時永遠不要調用ZeroMemory,這樣的話,struct就實際上跟class的用法一樣了。
總結
以上是生活随笔為你收集整理的C++ POD与结构体声明的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: _beginthreadex与Creat
- 下一篇: Windows服务编写综述