2012-02-24 32 views
0

根據(2003)標準的結構定義,它是一個類的特例,對成員,函數和基類使用不同的默認訪問修飾符。它也繼續將結構的要求定義爲POD結構。有沒有一個有效的用例,非POD結構比類更受歡迎?

C++ 2003標準,ISO 14882第9.0.4:

的結構是與類密鑰結構中定義的類;其成員和基類(第10條)默認公開爲 (第11章)。聯合是由類關鍵聯合定義的類;其成員默認由 公開,每次只保留一個數據成員(9.5)。 [注:類別類別的彙總在 8.5.1中描述。 ] POD-struct是一個聚合類,它沒有非POD-struct類型的非靜態數據成員,非POD-union(或這種類型的數組)或引用,並且沒有用戶定義的複製賦值運算符 並且沒有用戶定義的析構函數。類似地,POD聯合是不具有非靜態數據類型的非POD結構,非POD聯合(或這種類型的陣列)或參考的 成員集合體結合,並且沒有用戶定義 拷貝賦值運算符並沒有用戶定義的析構函數。 POD類是一個類,它是 POD結構或POD聯合。

根據這個定義,非POD結構和類之間的唯一區別因素是默認的訪問修飾符。

這是我能想象具有非POD結構的目的:

  • 他們的原有功能,需要維持向後兼容
  • 打字public:是很難的。

當非POD結構被假定爲其他系統的POD時會導致疼痛,例如當傳遞到C和返回時。爲了說明,this person ran into problems when a struct that was assumed to be POD was updated by another developer such that it was no longer POD。因爲缺省情況下編譯器沒有靜態聲明POD-ness,所以當運行時應用程序會在只能使用POD結構的上下文中使用時崩潰。更糟糕的是,我可以想象(儘管我不確定這是否可能),一個非POD結構在某些需要POD的情況下工作,並且在其他情況下失敗,從而導致錯誤和崩潰,這些都很難追查。

鑑於有些情況下,非POD結構可能導致奇怪和破碎的行爲領域,非POD結構的用途是什麼?爲什麼在編譯時靜態檢查POD-ness的結構(通過C++ 11中的std :: is_pod還是Boost等價物)?

+1

*「非POD結構和類之間的唯一區別因素是默認訪問修飾符」* - 它是struct和class * period *之間的唯一區別,不僅僅是非POD結構體/類。 – 2012-02-24 02:27:34

+0

這個問題真的很差。你真正要問的是「爲什麼'結構'只是'具有默認公共訪問器的類'?」它與POD或標準佈局或集合體的定義無關。 – 2012-02-24 02:49:44

+0

我很抱歉,我可能已經說得更好了。我的問題不是爲什麼結構和類是有區別的,而是爲什麼有可能創建一個不是POD的結構,當它們與具有一些不重要的差異的類相同時。對不起,我希望這可以更簡潔地描述我的問題。 – grahamp 2012-02-24 03:19:22

回答

4

我認爲這是一個毫無意義的歷史事故,坦率地說,關鍵字class根本不應該在C++中添加。好吧!

如果struct被要求爲POD,通常會很煩人 - 你經常從POD開始,只是因爲你可以將它稱爲「結構」,然後在很多時候不得不改變它當你決定讓它成爲非POD時,稍後再放置。

請注意,GCC(至少直到最近)並不關心你是否(向前)在一個地方聲明瞭一些類,並且在其他地方聲明瞭一個類,反之亦然。鏗鏘抱怨這種事情(因爲它有權利,儘管這會「破壞」一些現有的代碼)。

+0

編譯器有權發佈任何想要的診斷信息。但是,g ++ *必須接受*聲明中的差異。並且診斷它是[反作用愚蠢的警告](http://alfps.wordpress.com/2010/06/22/cppx-is-c4099-really-a-sillywarning-disabling-msvc-sillywarnings/),因爲它只能在無害的情況下診斷。 – 2012-02-24 02:10:41

+0

同樣的事情適用於模板專業化,您可以將類模板專門化爲結構,反之亦然。 – 2012-02-24 02:19:00

+0

*有權利這樣做[抱怨混合'struct'和'class'聲明] *我真的不這麼認爲,你能解釋爲什麼編譯器應該抱怨*嗎?它在哪裏說它不正確?請注意,在另一端,Visual Studio(在我看來,直到你證明我錯了)有一個問題,因爲它不同地破壞了struts和類的符號,而關於標準,唯一的區別是默認訪問說明符,它沒有在聲明中的作用......你是否在意解釋你的說法? – 2012-02-24 03:08:49

0

「 POD的煩躁不是靜態編譯器斷言默認」

哦?

#include <iostream>   // std::cout, std::endl 
#include <type_traits>  // std::is_pod 
#include <string>   // std::string, std::to_string 
using namespace std; 

struct A 
{ 
    int x; 
}; 

struct B 
{ 
    string s; 
}; 

int main() 
{ 
    static bool const a = is_pod<A>::value; 
    static_assert(a, "Ah..."); 
    static_assert(!is_pod<B>::value, "Bah!"); 
} 

struct被允許爲非POD的原因,例如, B以上,即爲什麼語言是這樣設計的,可能是在Bjarne Stroustrup ’的書中「 C++的設計和演化」。如果沒有,那麼可能只有Bjarne自己知道。因爲這個C++的一般性struct從一開始就一直存在。

+1

我不會說編譯器正在做'默認'。並不是說它應該。 – bames53 2012-02-24 02:06:55

+0

是的,我特別提到了std :: is_pod。我的問題更多的是「爲什麼它不默認*這樣做?」 – grahamp 2012-02-24 02:17:50

+0

@ barnes53:我不會說OP的聲明是有意義的,根本不存在任何語言規則要求編譯器聲明PODness,那麼這是什麼關於「默認」的呢?我看不到任何合理的解釋 – 2012-02-24 02:18:37

相關問題