C++ 为什么类成员与其对象具有相同的地址?

C++ 为什么类成员与其对象具有相同的地址?,c++,C++,在以下情况下,每个成员都有不同的名称或实体,为什么他们的地址相同 struct B { int x; }; struct A { B b; }; int main() { A obj; cout << &obj.b.x << endl; cout << &obj.b << endl; cout << &obj << endl; } 结构B{intx;}; 结构A{B

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

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

int main()
{
    A obj;
    cout << &obj.b.x << endl;
    cout << &obj.b << endl;
    cout << &obj << endl;
}
结构B{intx;}; 结构A{B;}; int main() { obj;
cout因为指向结构的指针总是指向它的第一个成员(因为结构是按顺序排列的)

(C1x§6.7.2.1.13:“适当地,指向结构对象的指针 已转换,指向其初始成员…反之亦然。可能 在“作为结构对象”中使用未命名的填充,但不能在其 开始。”)


<强>注释:曼奇指出,如果你开始向你的结构中添加虚拟函数,C++通过在结构的开始处对VTALE进行跟踪来实现这一点…这使得我的语句(对于C来说是正确的)当你谈论C++中的“结构”时,你可能会犯错误。

因为它们在同一个地方。Stult中的第一个元素是<代码>结构B < /C>,它们实际上在同一个内存位置(在代码< >结构中的任何东西,<代码> >之后将放在<代码> b>代码>下。

类似地,
x
struct B
中的第一位数据,因此它与
struct B
的位置相同


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

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


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

可能它们在同一个类中,因为您的内存看起来像-
class
es/Cuth>结构> /Calp> S是一个抽象概念,编译器可以优化 Stult。(这不是正确的答案,但它是要考虑的。)在<代码> CUT<代码>下,这似乎比<代码> C++ <代码>更“<代码> C++ >代码>,所以一般来说,指向结构的指针并不总是指向它的第一个成员。(以防万一有人浏览了你的链接却没有注意到区别。)废话…结构在C中与C++一样工作…OP使用<代码> CUT/CODE>实际上是除了这点之外。在<代码> C++ +<代码> A<代码>结构> <代码>只是一个<<代码>类> <代码>,默认访问“<代码>公用>代码>而不是<代码>私下<代码>。如果添加了<代码>结构> <代码>,将得到虚拟函数。指针,将导致它违反上述属性。使用<代码> CUT<代码>显示它是“代码> C++ +<代码>,而不是<代码>代码>代码>,因为<代码> C<代码>没有<代码> cOUT >代码>。“C样式结构”在C++中被称为“普通旧数据”。POD结构具有额外的布局限制,例如“指向初始成员的指针”。上面引用过。这适用于C++11中的任何标准布局类型。因此,它不仅仅是POD(尽管我认为包括我在内的大多数人在说POD时实际上是指标准布局类型)。+1“虚拟函数之类的东西会导致内容移动。”