gpt4 book ai didi

c++ - C++中 "Class instantiated object and variable inside the object address"的内存地址

转载 作者:行者123 更新时间:2023-11-27 23:54:37 24 4
gpt4 key购买 nike

我正在努力理解主程序中声明的变量与实例化类对象中的变量之间内存寻址差异的概念!

我的问题是,当我在主程序中声明两个变量(例如“int a, int b”)时,它需要 4+4 个字节,并且在内存中的某个位置有一个特定的两个地址。示例“a 在内存 0x248444 中,b 在 0x248448 中”……在这种情况下没问题……

当涉及到具有两个变量“int c,int d”的类实例化对象时,该对象采用8字节的内存地址,例如“0x248544”,那么“int c和int d”的地址呢?

所以 int c 和 int d 的地址在对象地址“0x248544”内?int c 和 int d 是否有特定地址?

如何理解/实例化类对象地址和该对象内部变量地址有什么区别?

希望我的问题很清楚....

在互联网上搜索后,我找到了一本名为“inside the C++ object model”的书,但对于实例化类对象中声明的变量和main中声明的变量的内存差异有基本的了解。有人请帮我说清楚。

提前致谢。

最佳答案

好的,你有一个像这样的 C 类:

class C
{
int c;
int d;
};

类 C (C c) 的实例将占用一些内存,它需要(假设 int 是 4 个字节大——虽然这不一定在所有机器上都是如此)8 个字节。

如果实例位于地址 0x248544,它将恰好占据该地址的字节 + 下一个后续字节。在上面这样一个没有任何进一步条件的简单类中,c 将占据这八个字节的前四个,d 将占据接下来的四个。

因此 c.c 与您的对象 c 具有完全相同的地址,而 c.d 位于四个字节之后,因此地址为 0x248548。

但是请注意,第一个成员不一定与您的对象具有相同的地址!让我们修改我们的 C 类:

class C
{
virtual ~C() { } // virtual destructor -> C gets virtual!
int c;
int d;
};

现在,sizeof(C) 将为 16(!)(前提是指针需要 8 字节存储空间,就像在现代 64 位硬件上一样)。为什么?该类获得一个指向 vtable 的附加指针,该指针通常是类 C 的第一个(但不可见)成员。

因此 c 仍将位于地址 0x248544,但现在指向 vtable 的(不可见)指针共享该地址; c.c在后面,因此位于地址0x2484c,c.d则位于0x24850。

在这方面,C++ 不同于 C,其中结构的第一个成员总是共享结构本身的地址...

虽然在 C 和 C++ 中,两个后续成员不一定必须相互“接触”,它们之间可能会填充一些字节 - 关键字字节对齐。

此外,C++ 允许对类的成员重新排序:而在 C 中,如果结构成员 ab 之前声明,则 a 必须放在 b 之前在内存中也是如此,这在 C++ 中只有具有相同可访问性的成员才需要!

class C
{
int a;
public:
int b;
private:
int c;
};

现在允许编译器保持顺序不变,但它也可以将 b 放在其他两个之前或之后 - 只有 a 不允许这样做放在 c 之后。

长话短说:所有这些内存布局的东西比您可能预期的要复杂得多...

vtables 旁注:vtable 指针不需要存在(相对于 C++ 标准)- 如果任何编译器供应商找到更好的解决方案来实现多态性,他们可以自由地这样做 - if 他们发现...但是 vtables 是当前最先进的技术,一种事实上的标准。

关于c++ - C++中 "Class instantiated object and variable inside the object address"的内存地址,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43520196/

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