亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

為什么C ++ 11的POD“標準布局”定義是這樣?

為什么C ++ 11的POD“標準布局”定義是這樣?

C++
倚天杖 2019-10-30 14:55:11
我正在研究C ++ 11中新的,寬松的POD定義(第9.7節)標準布局類是這樣的類:沒有非標準布局類(或此類數組)或引用的非靜態數據成員,沒有虛擬函數(10.3)和虛擬基類(10.1),對所有非靜態數據成員具有相同的訪問控制(條款11),沒有非標準布局的基類,在最派生的類中沒有非靜態數據成員,在一個非靜態數據成員中最多沒有一個基類,或者在非靜態數據成員中沒有基類,并且沒有與第一個非靜態數據成員相同類型的基類。我強調了令我驚訝的一點。如果我們允許數據成員具有不同的訪問控制,那會出什么問題?如果第一個數據成員也是基類,怎么辦?即struct Foo {};struct Good : Foo {int x; Foo y;};struct Bad  : Foo {Foo y; int x;};我承認這是一個奇怪的結構,但是為什么不應該Bad禁止它Good呢?最后,如果一個以上的構成類具有數據成員,那會出什么問題?
查看完整描述

3 回答

?
幕布斯6054654

TA貢獻1876條經驗 獲得超7個贊

您可以將標準布局類對象地址強制轉換為指向其第一個成員的指針,并通過后面的段落將其返回,這通常也可以在C語言中完成:


struct A { int x; };

A a;


// "px" is guaranteed to point to a.x

int *px = (int*) &a;


// guaranteed to point to a

A *pa = (A*)px; 

為此,第一個成員和complete對象必須具有相同的地址(編譯器無法通過任何字節調整int指針,因為它無法知道它是否是int的成員A)。


最后,如果一個以上的構成類具有數據成員,那會出什么問題?


在一個類中,成員根據聲明順序以遞增地址分配。但是,C ++并未規定跨類的數據成員的分配順序。如果派生類和基類都具有數據成員,則Standard不會故意為其地址定義順序,以便在內存布局方面為實現提供完全的靈活性。但是,要使上述演員表正常工作,您需要知道分配順序中的“第一個”成員是什么!


如果第一個數據成員也是基類,怎么辦?


如果基類與第一個數據成員具有相同的類型,則將基類放在內存中派生類對象之前的實現將需要在內存中派生類對象數據成員之前具有填充字節(基類的大小為1 ),以避免對基類和第一個數據成員使用相同的地址(在C ++中,相同類型的兩個不同對象始終具有不同的地址)。但是,這將再次使得無法將派生類對象的地址轉換為其第一個數據成員的類型。


查看完整回答
反對 回復 2019-10-30
?
隔江千里

TA貢獻1906條經驗 獲得超10個贊

基本上是關于與C ++ 03和C的兼容性:

  • 相同的訪問控制-允許C ++ 03實現使用訪問控制說明符作為對類的(組)成員重新排序的機會,例如為了更好地打包它。

  • 層次結構中有多個具有非靜態數據成員的類-C ++ 03沒有說基類位于何處,也沒有說明填充是否會存在于同類型的完整對象中的基類子對象中。

  • 基類和相同類型的第一個成員-由于第二條規則,如果基類類型用于數據成員,則它必須是空類。許多編譯器確實實現了空基類優化,因此Andreas關于具有相同地址的子對象的說法是正確的。我不確定標準布局類的含義是什么,這意味著基類子對象具有與相同類型的第一個數據成員相同的地址是不好的,但是基類子對象何時具有與不同類型的第一個數據成員相同的地址。[編輯:這是因為相同類型的不同對象具有不同的地址,即使它們是空的子對象也是如此。感謝約翰內斯]

的C ++ 0x大概可以有定義的那些東西都是標準布局類型也是如此,在這種情況下,它也將確定他們是如何布局,以它為標準布局類型相同的程度。Johannes的回答更進一步,請看他的示例,這些示例會干擾標準布局類的良好屬性。

但是,如果這樣做,則某些實現將被迫更改它們對類的布局方式,以適應新的要求,這對于C ++ 0x前后的不同版本的編譯器之間的結構兼容性造成了麻煩?;旧?,它破壞了C ++ ABI。

我對如何定義標準布局的理解是,他們著眼于在不破壞現有實現的情況下可以放寬哪些POD要求。因此,我假設不做任何檢查,以上是一些現有的C ++ 03實現確實使用類的非POD性質來執行與標準布局不兼容的示例。


查看完整回答
反對 回復 2019-10-30
?
POPMUISE

TA貢獻1765條經驗 獲得超5個贊

如果我們允許數據成員具有不同的訪問控制,那會出什么問題?


當前的語言表示,編譯器無法在相同的訪問控制下對成員重新排序。喜歡:


struct x

{

public:

    int x;

    int y;

private:

    int z;

};

這里x必須在y之前分配,但是相對于x和y對z沒有限制。


struct y

{

public:

    int x;

public:

    int y;

};

新的措辭說,y盡管有兩個publicS,但仍是POD 。這實際上是放寬規則。


查看完整回答
反對 回復 2019-10-30
  • 3 回答
  • 0 關注
  • 650 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號