且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

是否保证班级成员在内存中是连续的?

更新时间:2023-11-11 23:44:34

可以确保它们以声明的顺序以递增的地址出现.通常对于不介入访问说明符的数据成员而言,这是正确的,因此,如果类中还有其他数据成员,则它们可以进行干预的唯一方法就是其中存在访问说明符.

It is guaranteed that they appear with increasing addresses in the order declared. This is true in general of data members without intervening access specifiers, so if there are other data members in the class then the only way they could intervene is if there are access specifiers in there.

我认为修改填充字节不保证是安全的.我不保证该实现不会在数据成员之间放置重要的东西",尽管我无法立即想到实现会想要 放入其中的任何内容.设计奇怪的精确标记GC的类型信息?可识别的值以测试缓冲区超限吗?

I don't think it's guaranteed to be safe to modify padding bytes. I don't think it's guaranteed that the implementation won't put "something important" in between data members, although I can't immediately think of anything an implementation would want to put in there. Type information for a strangely-designed accurate-marking GC? Recognizable values to test for buffer overruns?

不能保证全零位表示空函数指针.

It's not guaranteed that all-bits-zero represents a null function pointer.

您可以使用以下方法处理全零位表示形式的问题:

You could deal with the issue of the all-bits-zero representation using something like:

std::fill(&func1, &func4 + 1, (void(*)(void))0);

但是这仍然会留下填充的问题.您可以确保在数组中没有填充,但不能(按标准)在类中.您的实现所使用的ABI可能会以必要的程度指定结构布局,以确保上述类与4个函数指针的数组相同.

but that would still leave the issue of padding. You're guaranteed no padding in an array, but not (by the standard) in a class. The ABI used by your implementation might specify struct layout to the degree necessary to ensure that your class above is laid out the same as an array of 4 function pointers.

另一种方法是执行以下操作:

An alternative is to do the following:

struct function_pointers {
    void (*func1)();
    void (*func2)();
    void (*func3)();
    void (*func4)();
};

class C : private function_pointers
{
public:
    C() : function_pointers() {}
};

初始化程序 function_pointers()规定(由于它没有用户声明的构造函数) function_pointers 的成员被零初始化,即使 C 本身仅是默认初始化的.如果您想输入更多内容来访问 func1 等,则 function_pointers 可以是数据成员而不是基类.

The initializer function_pointers() dictates that (since it doesn't have a user-declared constructor) the members of function_pointers are zero-initialized even if the instance of C itself is only default-initialized. function_pointers could be a data member rather than a base class, if you prefer to type a bit more to access func1 etc.

请注意,在C ++ 03中, C 现在不是POD.在C ++ 11中, C 保留此更改后的标准布局,但如果 C 中定义了任何数据成员,则不会成为标准布局,并且不是琐碎的类.因此,如果您依赖POD/标准/琐碎性,则不要这样做.取而代之的是保留 C 的定义,并使用聚合初始化( C c = {0}; )对C的实例进行零初始化.

Note that C is now non-POD in C++03. In C++11 C remains standard-layout after this change, but would not be standard-layout if there were any data members defined in C, and it is not a trivial class. So if you were relying on POD/standard/trivial-ness then don't do this. Instead leave the definition of C as it is and use aggregate initialization (C c = {0};) to zero-initialize instances of C.