c++ - 为什么c++中类的大小取决于数据成员的公共(public)私有(private)状态?

据我所知,C++ 中一个类的大小取决于以下因素 -

  • 所有非静态数据成员的大小。
  • 数据成员的顺序。
  • 是否启用字节填充。
  • 其直接基类的大小。
  • 虚函数的存在。
  • 继承方式(虚拟继承)。
  • 现在我创建了 2 个类,如下所示 -
    class A{
        int a;
        short s;
        int b;
        char d;
    };// kept a char at last on purpose to leave a "hole"
    
    class B : public A{
        char c;  
    };
    

    现在检查 A 和 B 的大小我看到
  • A 的大小:16
  • B 的大小:16
  • 我的假设是 B 类中的字符c 被容纳在 A 类留下的“洞”中。

    但是,让我困惑的是下面的场景,其中我让成员公开
    class A{
        public:
        int a;
        short d;
        int b;
        char s;
    };
    
    class B : public A{
        public:
        char c;
    };
    

    现在大小变成
  • A 的大小:16
  • B 的大小:20
  • 我似乎无法理解这种差异的原因。

最佳答案

安腾 ABI uses the C++03 definition of POD定义“用于布局的POD”类。在 C++03 中,拥有私有(private)数据成员会使类失去作为聚合的资格,因此失去了 POD 的资格:
 

POD-struct is an aggregate class that has no non-static data members of type non-POD-struct, non-POD-union (or array of such types) or reference, and has no user-defined copy assignment operator and no user-defined destructor.



作为 POD 类(class) disables tail padding reuse :
 

The dsize, nvsize, and nvalign of these types are defined to be their ordinary size and alignment. These properties only matter for non-empty class types that are used as base classes. We ignore tail padding for PODs because an early version of the standard did not allow us to use it for anything else and because it sometimes permits faster copying of the type.



因此,在您的第一个示例中,A不是用于布局目的的 POD,其尾部填充可用于 B::c ,但在你的第二个例子中,它是一个 POD,它的尾部填充不能被重用。                                                                 

arrays - 查找数组长度的时间复杂度 - 程序员与数组

matlab - matlab中的向量条目查找 - 程序员与数组

java - java wsdl什么wsdl元素解析为java类? - 程序员与数组

Python fastavro 错误地转换浮点数 - 程序员与数组

asp.net - <system.web> 和 <system.webServer> 之间的区别? - 程序员与数组

java - 根据Java中的最新时间戳从列表中查找唯一记录 - 程序员与数组

vector - 用于映射图块的 AutoCAD 绘图 (DWG) - 程序员与数组

asp.net - 在 appSettings 中存储字符串数组? - 程序员与数组

string - 如何在同一规则中将字符串解析和块解析混合在一起? - 程序员与数组

asp.net - ASP.net页面在导入语句时出错,但是我确实有引用吗? - 程序员与数组

javascript - 将executeScript内编写的脚本内的javascript变量值提取并存储到普通java变量中 - 程序员与数组

qt - 如何将 QPixmap 对象保存到文件? - 程序员与数组

Django editable=False 仍然显示在字段集中? - 程序员与数组

ios - 如何在横向的 SwiftUI 中的 Master-Detail 1-Detail 2View 中显示缺少的后退按钮? - 程序员与数组

vb.net - 在VB.Net中构造一个对象并调用一个方法而无需赋值 - 程序员与数组

sql - phpMyAdmin 对我的 UNION ALL 查询做了什么? - 程序员与数组

java - 如何总结两个日期之间的蒙古语吗? - 程序员与数组

c++ - 为什么c++中类的大小取决于数据成员的公共(public)私有(private)状态? - 程序员与数组

asp.net-mvc - 避免@html.checkboxfor foreach - 程序员与数组

R 统计信息 : problem with simple column vector - 程序员与数组