【问题标题】:Why do class members have the same address as their object?为什么类成员的地址与其对象相同?
【发布时间】:2023-03-07 09:53:01
【问题描述】:

在以下情况下,每个成员都有不同的名称或实体,为什么他们的地址相同?

struct B { int x; };
struct A { B b; };

int main()
{
    A obj;
    cout << &obj.b.x << endl;
    cout << &obj.b << endl;
    cout << &obj << endl;
}

【问题讨论】:

  • 可能他们在同一班
  • 因为你的内存看起来是这样的 - classes/structs 是一个抽象概念,编译器可以优化 structs 出来。 (这不是正确的答案,但值得考虑。)

标签: c++


【解决方案1】:

因为指向结构的指针总是指向它的第一个成员(因为结构是按顺序排列的)。

In C, does a pointer to a structure always point to its first member?

(C1x §6.7.2.1.13: "一个指向结构对象的指针,适当地 转换后,指向其初始成员……反之亦然。也许有 作为结构对象内的未命名填充,但不在其 开始。”)

注意: mange 正确地指出,如果您开始向结构添加虚函数,C++ 会通过在结构的开头添加 vtable 来实现这一点......这就是我的陈述(这对 C 来说是正确的)当您谈论在 C++ 中使用“结构”可能做的所有事情时,这是不正确的。

【讨论】:

  • 鉴于cout,这似乎比C++ 更多C,因此通常指向结构的指针并不总是指向其第一个成员。 (以防有人浏览您的链接而没有注意到其中的区别。)
  • 废话......结构在 C 中的工作方式与在 C++ 中的工作方式相同......而且 OP 对 cout 的使用真的不是重点。
  • C++ 中,struct 只是一个class,默认访问权限为public,而不是private。如果您添加带有虚函数的struct,它将获得一个 vtable 指针,这将导致它违反上述属性。使用cout 表明它是C++,而不是C,因为C 没有cout
  • “C 风格的结构”在 C++ 中被称为“普通旧数据”。 POD 结构有额外的布局限制,例如上面引用的“指向初始成员的指针”。
  • 这适用于 C++11 中的任何标准布局类型。因此,它不仅仅是 POD(尽管我认为包括我在内的大多数人在说 POD 时实际上是指标准布局类型)。
【解决方案2】:

如果你手里拿着一杯咖啡站在你国家的边界​​上,那么你的坐标、边界坐标和咖啡杯的坐标在 GPS 设备上都将具有相同的值。

第一个孩子的第一个元素恰好位于对象的起始地址。名称是为了您自己方便计算机使用内存地址。您可以随意命名它们,但内存布局取决于数据成员的顺序和层次结构。

【讨论】:

    【解决方案3】:

    因为他们在同一个地方。 struct A 中的第一个元素是 struct B,因此它们实际上位于相同的内存位置(struct A 中的任何其他内容都将放在 b 之后)。

    同样,xstruct B 中数据的第一位,所以它与struct B 的位置相同。

    请务必注意,这并不总是正确的。像虚函数这样的东西会导致东西移动。在这种情况下是正确的,因为它们是普通的类/结构。

    【讨论】:

    • +1 "像虚函数这样的东西会导致东西移动。"
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-06-18
    • 2012-07-21
    • 2011-06-11
    • 2013-12-22
    • 1970-01-01
    • 1970-01-01
    • 2012-04-05
    相关资源
    最近更新 更多