代码之家  ›  专栏  ›  技术社区  ›  Iliketoproveit

结构中的内存布局差异

  •  6
  • Iliketoproveit  · 技术社区  · 8 年前

    我在C中有以下结构++

    struct A {
      int a;
      double b;
      float c;
    }
    

    此结构与添加了函数的结构之间的内存布局是否有差异?

    struct B {
      int a;
      double b;
      float c;
      void foo();
    }
    B::foo() { //do stuff }
    
    4 回复  |  直到 7 年前
        1
  •  8
  •   Benjamin Barrois    8 年前

    C++标准保证C结构和C++类(或结构——相同的东西)的内存布局是相同的,前提是C++类/结构符合POD(“普通旧数据”)的标准。那么POD是什么意思呢?

    如果满足以下条件,则类或结构为POD:

    所有数据成员都是公共的,其本身是POD或基本类型(但不是引用或指向成员类型的指针),或此类类型的数组

    • 它没有用户定义的构造函数、赋值运算符或析构函数
    • 它没有虚拟功能
    • 它没有基类

    因此,在您的情况下,内存布局是相同的。

    资料来源: Structure of a C++ Object in Memory Vs a Struct

        2
  •  7
  •   YSC    7 年前

    此结构与添加了函数的结构之间的内存布局是否有差异?

    可能吧。

    自从 A B 是标准布局 1. ,它们的公共初始序列由每个非静态数据成员组成 2. ,他们是 布局兼容

    该标准只描述抽象机器的语义,因此没有 保证 类型的对象 A. 将在内存中表示为类型为的对象 B 但是 布局兼容 类型往往是。


    (1) [class]/7

    标准布局类是指:

    • 没有非标准布局类(或此类类型的数组)或引用类型的非静态数据成员,
    • 没有虚拟函数(10.3)和虚拟基类(10.1),
    • 对所有非静态数据成员具有相同的访问控制(第11条),
    • 没有非标准布局基类, 在大多数派生类中没有非静态数据成员,并且最多有一个基类具有非静态数据成员,或者没有基类具有非静态数据成员,以及
    • 没有与第一个非静态数据成员类型相同的基类。

    (2) [class.mem]/21 & [class.mem]/22

    如果两个标准布局结构(第9条)类型具有相同数量的非静态数据成员,并且相应的非静态数据成员(按声明顺序)具有布局兼容类型(3.9),则它们是布局兼容的。

        3
  •  2
  •   Quentin    8 年前

    这在形式上取决于编译器,但如果编译器声明非虚拟成员函数会更改类的布局,则可能会造成破坏。您需要这种稳定性来加强共享对象依赖于每个平台的兼容性。

        4
  •  1
  •   Aconcagua    8 年前

    是和否。。。

    在您的特定情况下,不会。结构只不过是一个数据容器,函数驻留在其他地方。调用该函数时,指向该结构的指针作为附加的隐式第一个参数传递,该参数显示为 this 函数中的指针。

    但是,如果您添加 事实上的 作用虽然C++标准没有强制要求它,但vtables是 事实上 标准,并且该类将作为第一个但不可见的成员接收指向vtable的指针。您可以通过在添加虚拟函数之前和之后打印出对象的大小来尝试这一点。

    另一方面,如果 虚拟已经因为继承了另一个已经有虚拟函数的类,所以内存布局不会再改变,因为已经有一个指向包含的vtable的指针(尽管它将指向子类实例的不同位置)。