【问题标题】:Is order in memory guaranteed for class private members in C++?C++ 中的类私有成员是否保证内存中的顺序?
【发布时间】:2017-12-01 11:50:28
【问题描述】:
class my_class_t {

private:
    uint64_t field1;
    uint64_t field2;
};

C++ 标准是否保证内存中field1field2 的顺序?

UPD。答案说field2是,但&field2可能不等于&field1 + 1。如何确保field2 紧跟在field1 之后?

【问题讨论】:

    标签: c++ c++14 class-members


    【解决方案1】:

    保证它们的地址相互增加([class.mem]/13):

    (非联合)类的非静态数据成员具有相同的访问权限 控制(子句[class.access])被分配以便以后的成员 在类对象中有更高的地址。

    注意我用粗体标记的文本。虽然保证field2field1 之后它们都是私有的,但如果它们具有不同的访问控制,则不必如此。当然,中间填充始终是一种选择。

    但是如果你想强制没有填充,并且它们是相同的类型,一个数组就可以了:

    uint64_t field[2];
    

    它还使&field[0] + 1 定义良好,因为这些对象现在显然是同一个数组的成员。

    【讨论】:

    • 谢谢!请查看问题的更新:)
    • @Incomputable - 也许吧。这与我愿意说的一样确定。整个事情是非常实现定义的。
    • @vladon - 由于它们属于同一类型,您可以通过将它们放入数组中来确保缺少填充 uint64_t field[2]; - 但这并不漂亮
    • @Incomputable - 你让我还在想它 :)
    • @Bathsheba - 哦,刚刚?不久前我打乱了机器人并投票赞成你的;)
    【解决方案2】:

    是的,订单是有保证的。

    field1 的地址必须与my_class_t 实例的地址相同。 field2field1 有一个“更高”的地址,因为reinterpret_castfield1 地址上获得的unsigned char* 指针的正指针运算最终将到达field2 占用的内存。

    但请注意,通过指针算术对指向field1 的指针尝试“到达”field2 的行为未定义

    至于确保成员之间没有填充,您不能在可移植的 C++ 中做到这一点。但是你可以使用数组类型:

    class my_class_t {
    private:
        uint64_t fields[2];
    };
    

    保证这一点。然后您可以使用指针算法访问成员。

    【讨论】:

      【解决方案3】:

      访问限定符不干预时,对象在内存中的顺序与声明顺序相同。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-12-29
        • 2011-02-26
        • 2013-11-17
        • 1970-01-01
        • 2011-02-26
        • 2014-11-27
        • 2010-09-21
        • 1970-01-01
        相关资源
        最近更新 更多