5

我有这样的课:

class Object {
public: 
    unsigned char data[8];
    // other variables
    // functions etc...
 };

问题是 - 对象成员是否都存储在内存中相对于对象的相同位置?所以如果我有一个数组:对象数组[3],给定一个字符指针 char* data_ptr = array[0].datadata_ptr + (sizeof(Object))那么总是指向数组[1].data?

(我已经阅读了一些关于如何在类和结构的数据成员之间进行填充的 Q/As - 但我认为它们没有回答我的问题。)

在此先感谢,本

4

5 回答 5

4

sizeof Object已经包括类的所有内部填充Object。包括结尾处的任何填充。数组不允许任何额外的填充。因此,确实data_ptr + sizeof Object会有 的地址array[1].data

但是我不确定这是否真的被允许。也就是说,编译器可能被允许假定您永远不会将大于 8(成员数组的大小data)的值添加到array[0].data,因此如果您违反规则,它可能会应用失败的优化。也就是说,您的代码实际上可能表现出未定义的行为(这是“允许编译器在这种情况下做任何事情”的标准术语)。

但是,由于您使用的是指向 的指针char,对于该指针有更多的许可规则(您可以做许多char*一般类型无法做到的事情),因此它可能实际上是定义的行为。

于 2012-08-19T10:00:04.340 回答
2

如果您的问题的目的是了解内存中的内容,那么它是可以接受的。

但是,如果您想真正做到这一点:您想做的实际上是对所有同事的犯罪。

在 C++ 中进行集合的正确方法不是使用数组,而是使用std::vector或另一个 std 集合(如果确实需要)。我们不应该再使用 C 算术,而是通过迭代器访问向量集合的项目。这就是 C++ 标准库的原因:-)

于 2012-08-19T10:19:37.590 回答
1

我认为答案是“也许”,这意味着你不应该赌这个。最好的方法是在 IDE 调试器上查找内存地址。当您引入编译器可以优化的成员和方法时,您会发现这很容易被抛弃。例如,任何常量或不访问任何可能是静态的成员的方法。前任:

void Object::doSomething() {std::cout << "something\n" << std::endl;}

我相信这实际上在静态分配中得到了优化,因为我最近了解到,((Object)NULL).doSomething();在你为Object.

于 2012-08-19T10:00:22.933 回答
1

有许多因素决定了 C++ 中类的对象的大小。这些因素是: - 所有非静态数据成员的大小 - 数据成员的顺序 - 字节对齐或字节填充 - 其直接基类的大小 - 虚函数的存在(使用虚函数的动态多态性)。- 正在使用的编译器 - 继承模式(虚拟继承)

在这里检查:http ://www.cprogramming.com/tutorial/size_of_class_object.html

于 2012-08-19T10:00:43.737 回答
1

是的,相对于对象基址的布局将是不变的。这是 ABI 的要求。对象和数组的任何间距或填充也由 ABI 指定。

于 2012-08-19T10:01:31.207 回答