C++ sizeof类是否保证只包含元素的大小

C++ sizeof类是否保证只包含元素的大小,c++,sizeof,C++,Sizeof,给定示例类 class test { public: test(); ~test(); void someMethod(); void someOtherMethod(); private: int var; }; 是sizeof(test)==sizeof(int),还是我们不能做出这样的假设?它是否依赖于平台/编译器 编辑: 这样做的动机是通过流读/写类。类确实包含一个整数,使用一些方便的访问方法-整数的最高顺序字节保留给标志,低3个字节表示整数24位数字。有鉴于此,我们的想法是编写此类

给定示例类

class test
{
public:
test();
~test();
void someMethod();
void someOtherMethod();

private:
int var;
};
sizeof(test)==sizeof(int)
,还是我们不能做出这样的假设?它是否依赖于平台/编译器

编辑:


这样做的动机是通过流读/写类。类确实包含一个整数,使用一些方便的访问方法-整数的最高顺序字节保留给标志,低3个字节表示整数24位数字。有鉴于此,我们的想法是编写此类类变量的数组,并在需要时将其作为纯int读取。“有可能的答案”这一问题并没有涉及到这一方面——更多的是关于用多个元素填充的问题。

你不能这样假设

允许编译器添加填充以提高性能。可能您的目标系统只能读取64位值。读取较小的值需要读取64位,然后屏蔽为32位。在这样的系统上,只需将类填充到64位就更有效了

如果您确实需要一个类或结构作为您请求的确切大小,那么几乎每个编译器都有属性或pragma来控制填充。

一般来说,您不能假设某个任意类的大小只是其成员大小的聚合。一般来说,你也不应该在意*。编译器可以并且将更改类的大小,使它们的大小是某些特定字节数的倍数。它这样做的原因是为了提高性能。每个平台的字节数是不同的

在这个具体的例子中,事实上可能是
sizeof(test)
==
sizeof(int)
,但我怀疑这是引发这个问题的真正代码

有一些方法可以确保它做到这一点,但它们依赖于特定于平台的功能

首先,确保你的班级是一个豆荚,所有的成员都是豆荚

其次,将packing设置为1字节。在GCC和MSVC下,执行此操作的指令类似于:

#pragma pack (1)
您应该在不严格需要时关闭此包装,因为它可能会对性能产生负面影响:

#pragma pack (push, 1)

class test
{
public:
  void someMethod();
  void someOtherMethod();

  int var;
};

#pragma pack (pop)
注意,上面我删除了
private
部分。如果类具有非
静态
私有
受保护的
数据成员,则该类不是POD。出于同样的原因,我还删除了默认构造函数和析构函数

在MSVC和GCC下,
sizeof(test)
将等于
sizeof(int)


POD:普通的旧数据类型。为了使类(或结构)成为POD,它必须没有用户定义的析构函数或构造函数、复制赋值运算符,并且没有指向成员的指针类型的非
静态
成员。此外,它必须没有
虚拟
成员、没有
私有
受保护
静态
成员,并且没有基类。此外,它确实拥有的任何非
静态
数据成员也必须是POD本身。换句话说,就是普通的旧(公共)数据



“你也不应该在意。”一般来说,你需要确保某个类的大小正好是成员的大小的唯一时间是在系统的边界上。例如,当通过套接字将数据移入或移出程序时。编译器填充类是有原因的。除非有特定的、可证明的原因,否则不应在此重写编译器。

尽管我怀疑任何编译器都不会在其中添加填充,但它可以。请注意,您的类没有虚拟函数和虚拟基类等,这简化了它。如果您的类有任何虚拟对象,那么您可以相当自信地认为其大小将大于
sizeof(int)
(尽管标准没有保证)。目前看来,很可能是
sizeof(test)==sizeof(int)
,但标准肯定不能保证这一点(编译器可以使其变大;它可能无法使其变小)。我必须指出,除非您将数据移入或移出程序,您通常不应该关心您的类的大小与成员的大小不一样。这是一个微观问题。除非您能够证明类的大小是代码中的一个特定瓶颈,否则采取步骤确保它具有特定大小是一个过早的微观优化。John Dibling是的,这样做的动机是通过类似流的流来读/写整个类。write((char*)classVar,sizeof(test))@伊利亚科贝列夫斯基:好吧,这是一个合理的理由。进行此操作时请注意endianness。
static_assert(sizeof(test)==sizeof(int))
将在这里提供很大帮助。非常感谢您提供了这个非常详细的答案。即使没有对齐,msvc上的强制大小也会匹配。我将使用Cory Nelson建议的静态断言方法,而不是强制对齐-只要问题可以在编译时检测到,它是安全的。顺便说一句,POD不是必需的,只有标准布局。然后
int
也将被填充。。。