47

C ++ 11の新しいリラックスしたPOD定義を調べています(セクション9.7)

標準レイアウトクラスは、次のようなクラスです。

  • タイプnon-standard-layoutクラス(またはそのようなタイプの配列)または参照の非静的データメンバーはありません。
  • 仮想関数(10.3)および仮想基本クラス(10.1)がなく、
  • すべての非静的データメンバーに対して同じアクセス制御(条項11)があり
  • 非標準レイアウトの基本クラスはありません。
  • 最も派生したクラスに非静的データメンバーがなく、非静的データメンバーを持つ基本クラスが多くても1つないか、非静的データメンバーを持つ基本クラスがない。
  • 最初の非静的データメンバーと同じタイプの基本クラスはありません。

私は私を驚かせたビットを強調しました。

さまざまなアクセス制御を持つデータメンバーを許容した場合、何が問題になりますか?

最初のデータメンバーが基本クラスでもあった場合、何が問題になりますか?すなわち

struct Foo {};
struct Good : Foo {int x; Foo y;};
struct Bad  : Foo {Foo y; int x;};

私はそれが奇妙な構造であることを認めます、しかしなぜ禁止されるべきBadであるが禁止されるべきではないのGoodですか?

最後に、複数の構成クラスにデータメンバーがある場合、何が問題になりますか?

4

6 に答える 6

25

これは基本的に C++03 および C との互換性に関するものです。

  • 同じアクセス制御 - C++03 実装では、クラスのメンバー (のグループ) を並べ替える機会として、アクセス制御指定子を使用できます。たとえば、より適切にパックするためです。
  • 非静的データ メンバーを持つ階層内の複数のクラス - C++03 は、基本クラスがどこにあるか、または同じ型の完全なオブジェクトに存在する基本クラスのサブオブジェクトでパディングが省略されるかどうかを示しません。
  • 基本クラスと同じ型の最初のメンバー - 2 番目の規則により、基本クラスの型がデータ メンバーに使用される場合、それは空のクラスでなければなりません。多くのコンパイラは空の基本クラスの最適化を実装しているため、同じアドレスを持つサブオブジェクトについて Andreas が言っていることは真実です。基本クラスのサブオブジェクトが同じタイプの最初のデータメンバーと同じアドレスを持つことは悪いことを意味する標準レイアウトクラスについてはわかりませんが、基本クラスのサブオブジェクトがいつ持っているかは問題ではありません異なるタイプの最初のデータ メンバーと同じアドレス。[編集: 空のサブオブジェクトであっても、同じタイプの異なるオブジェクトは異なるアドレスを持つためです。ヨハネスに感謝】

C++0x はおそらく、それらも標準レイアウト型であると定義できた可能性があります。その場合、標準レイアウト型と同じ程度に、それらのレイアウト方法も定義します。ヨハネスの答えはこれにさらに踏み込みます。これらが干渉する標準レイアウトクラスの素晴らしいプロパティの彼の例を見てください。

しかし、そうすると、一部の実装では、新しい要件に合わせてクラスのレイアウト方法を変更せざるを得なくなります。これは、C++0x 前後のコンパイラの異なるバージョン間の構造体の互換性にとって厄介です。基本的に、C++ ABI を壊します。

標準レイアウトがどのように定義されたかについての私の理解は、彼らが既存の実装を壊すことなく緩和できる POD 要件を検討したということです。したがって、チェックせずに、上記は既存の C++03 実装の一部がクラスの非 POD の性質を使用して、標準レイアウトと互換性のないことを行う例であると想定しています。

于 2011-08-23T12:47:59.030 に答える
8

さまざまなアクセス制御を持つデータ メンバーを許容すると、何が問題になるでしょうか?

現在の言語では、コンパイラは同じアクセス制御の下でメンバーを並べ替えることができないと言われています。お気に入り:

struct x
{
public:
    int x;
    int y;
private:
    int z;
};

ここで、x は y の前に割り当てる必要がありますが、x と y に対する z の制限はありません。

struct y
{
public:
    int x;
public:
    int y;
};

新しい言い回しは、2 つの syにもかかわらず、それはまだ PODであると言います。publicこれは実際にはルールの緩和です。

于 2011-08-23T12:50:54.227 に答える
4

許可されていない理由についてBadは、私が見つけた記事から引用させてください。

これにより、同じクラス型を持ち、同じ最派生オブジェクトに属する 2 つのサブオブジェクトが同じアドレスに割り当てられないようになります。

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2172.html

于 2011-08-23T12:30:07.133 に答える
2

箇条書き 5 から、最も派生したクラスには非静的データ メンバー (int) があり、非静的データ メンバーを持つ基本クラスを持つことはできないため、両方とも非ポッドのようです。

私はそれを次のように理解しています:「「基本」クラスの1つ(つまり、クラス自体または継承元のクラスの1つ)のみが非静的データメンバーを持つことができます」

于 2011-08-23T12:26:16.790 に答える
1

struct GoodFoo と Good には非静的データメンバーがあるため、標準レイアウトでもありません。

このように、Good は次のようになります。

struct Foo {int foo;};
struct Good : public Foo {Foo y;};

これは 6 番目のブレットを満たしていません。というわけで第6弾?

于 2011-08-23T12:31:03.580 に答える