gpt4 book ai didi

c++ - 为什么C++1 1's POD "标准布局“定义是这样的?

转载 作者:IT老高 更新时间:2023-10-28 14:02:04 26 4
gpt4 key购买 nike

我正在研究 C++11 中新的、宽松的 POD 定义(第 9.7 节)

A standard-layout class is a class that:

  • has no non-static data members of type non-standard-layout class (or array of such types) or reference,
  • has no virtual functions (10.3) and no virtual base classes (10.1),
  • has the same access control (Clause 11) for all non-static data members,
  • has no non-standard-layout base classes,
  • either has no non-static data members in the most derived class and at most one base class with non-static data members, or has no base classes with non-static data members, and
  • has no base classes of the same type as the first non-static data member.

我已经突出显示了令我惊讶的部分。

如果我们容忍具有不同访问控制的数据成员会出现什么问题?

如果第一个数据成员也是基类会出现什么问题?即

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

我承认这是一个奇怪的结构,但为什么应该禁止 Bad 而禁止 Good

最后,如果多个组成类有数据成员会出现什么问题?

最佳答案

您可以将标准布局类对象地址转换为指向其第一个成员的指针,然后由后面的一段返回,这在 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;

为此,第一个成员和完整对象必须具有相同的地址(编译器无法通过任何字节调整 int 指针,因为它无法知道它是否是 A 与否)。

Finally, what would go wrong if more than one constituent class had data members?

在一个类中,成员按照声明顺序分配在递增的地址中。然而,C++ 并没有规定跨类的数据成员的分配顺序。如果派生类和基类都具有数据成员,则标准不会故意为它们的地址定义顺序,以便在布局内存时为实现提供充分的灵 active 。但是要使上述类型转换起作用,您需要知道分配顺序中的“第一个”成员是什么!

What would go wrong if the first data member was also a base class?

如果基类与第一个数据成员具有相同的类型,则将基类放在内存中派生类对象之前的实现需要在派生类对象数据成员之前有一个填充字节(基类将大小为 1),以避免基类和第一个数据成员具有相同的地址(在 C++ 中,相同类型的两个不同对象总是具有不同的地址)。但这又会导致无法将派生类对象的地址转换为其第一个数据成员的类型。

关于c++ - 为什么C++1 1's POD "标准布局“定义是这样的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7160901/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com