关于c ++:sizeof类是否保证仅包含元素的大小

Is sizeof class guaranteed to contain size of elements only

本问题已经有最佳答案,请猛点这里访问。

给定的示例类

1
2
3
4
5
6
7
8
9
10
11
class test
{
public:
test();
~test();
void someMethod();
void someOtherMethod();

private:
int var;
};

sizeof(test) == sizeof(int)还是我们不能做这样的假设?是否依赖于平台/编译器?

编辑:

这样做的动机是通过流来读/写类。类确实包含一个整数,使用一些方便的访问方法-整数的最高顺序字节为标志保留,3个较低的字节表示整数24位数字。考虑到这一点,我们的想法是编写此类类变量的数组,并在需要时将其作为纯int进行读取。引用为有可能的答案的问题并不能解决这个问题——更多的是用多个元素填充。


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

在这个特定的例子中,事实上可能是sizeof (test)==sizeof (int),但我怀疑这是导致这个问题的真正代码。

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

首先,确保你的课程是一个pod*并且所有成员都是pod。

第二,将包装设置为1字节。在GCC和MSVC下,执行此操作的说明类似于:

1
#pragma pack (1)

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

1
2
3
4
5
6
7
8
9
10
11
12
#pragma pack (push, 1)

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

  int var;
};

#pragma pack (pop)

注意上面我去掉了private部分。如果类具有nonstaticprivateprotected数据成员,则它不是pod。我也出于同样的原因删除了默认的构造函数和析构函数。

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

pod:普通的旧数据类型。为了使类(或结构)成为POD,它必须没有用户定义的析构函数或构造函数、复制赋值运算符,并且没有指向成员的指针类型的非static成员。此外,它必须没有virtuals,没有privateprotectedstatic成员,没有基类。此外,它所拥有的任何nonstatic数据成员也必须是pods本身。换句话说,只是简单的旧(公共)数据。

"你也不应该在意。"一般来说,你只需要确保某个类的大小与成员的大小完全一致就可以了。例如,当通过套接字将数据移入或移出程序时。编译器出于某种原因填充类。除非您有特定的、可证实的原因,否则不应在此中重写编译器。


你不能这样假设。

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

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