c++ - 对 C++ 基类布局感到困惑

标签 c++ inheritance layout struct padding

这是我的代码

#include <bits/stdc++.h>


class A{
    int val;
    char c;
};
class B:public A{
    char val;
};

struct C{
    int val;
    char c;
};
struct D:public C{
    char val;
};


int main()
{
    std::cout<<sizeof(B)<<std::endl; //8
    std::cout<<sizeof(D)<<std::endl; //12

}

为什么classstruct 有不同的对齐方式

*** Dumping AST Record Layout
   0 | class A
   0 |   int val
   4 |   char c
     | [sizeof=8, dsize=5, align=4
     |  nvsize=5, nvalign=4]


*** Dumping AST Record Layout
   0 | class B
   0 |   class A (base)
   0 |     int val
   4 |     char c
   5 |   char val
     | [sizeof=8, dsize=6, align=4
     |  nvsize=6, nvalign=4]


*** Dumping AST Record Layout
   0 | struct C
   0 |   int val
   4 |   char c
     | [sizeof=8, dsize=8, align=4
     |  nvsize=8, nvalign=4]


*** Dumping AST Record Layout
   0 | struct D
   0 |   struct C (base)
   0 |     int val
   4 |     char c
   8 |   char val
     | [sizeof=12, dsize=9, align=4
     |  nvsize=9, nvalign=4]

最佳答案

struct案例考虑这个程序:

void f(C& cx)
{
    cx.c = 'x';
}

int main()
{
    D d{};
    d.D::val = 'y';
    f(d);
    std::cout << d.D::val << '\n';
}

此代码必须输出 y .

在您的系统上,AC结构的大小为 8因为有一个大小为 4 的成员和一个字符,并且结构必须与其最大成员正确对齐。这些结构有 4 个字节的 int、1 个字节的 char 和 3 个填充字节。

作业cx.c = 5;允许修改填充(任何结构赋值都可以修改结构填充)。因此,该填充不能用于存储基类元素。

然而,A 没有类似的例子。和 B因为 A 的数据成员是私有(private)的。不能有函数void f(A& ax) { ax.c = 'x'; }所以这个问题不会出现,编译器可以使用 A 的填充区域。存储派生类成员。

注意:两个类都不是 standard layout由于在基类和派生类中都有数据成员。

关于c++ - 对 C++ 基类布局感到困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61515206/

相关文章:

c++ - 强制 MS VS2010 在每次构建时重建一个 cpp 文件

c++ - 没有这样的插槽 QProgressBar::setValue(const int)

Java 在设计上避免了instanceof

c# - 内部和外部接口(interface)和集合

javascript - 在 ExtJS 4.x 的边框布局中折叠面板时出现错误

Python Kivy 如何将用 Python 制作的小部件注入(inject) kv 文件中的布局

c++ - 我可以在 C++ 中通过 operator[] 正确设置 std::vector 的第 n 个值吗?

c# - 实现 IEquatable 时隐藏基类方法

java - 如何消除 MigLayout 中两个单元格之间的垂直间隙?

java - 简单的图形程序