C++空类大小的探讨

本文最后更新于:2022年10月28日 下午

对几个网站的内容整合了一下,结尾有参考链接

GeeksforGeeks

Empty class: It is a class that does not contain any data members (e.g. int a, float b, char c, and string d, etc.) However, an empty class may contain member functions.

Suppose, if a class does not have any size, what would be stored on the memory location? That’s the reason when we create an object of an empty class in a C++ program, it needs some memory to get stored, and the minimum amount of memory that can be reserved is 1 byte. Hence, if we create multiple objects of an empty class, every object will have a unique address.

There is an interesting rule that says that an empty base class need not be represented by a separate byte. So compilers are free to make optimization in case of empty base classes.

StackOverflow

That’s really an implementation detail. Once long ago, I thought it could be zero bytes or a thousand bytes, that it has no bearing on the language specification. But, after looking at the C++17 standard (expr.sizeof), sizeof is defined as always returning one or greater, no matter what.

The size of a most derived class shall be greater than zero.

This is required for, among other things, allowing you to handle arrays of objects and pointers to them. If your elements were allowed to be zero-sized then &(array[0]) would be identical to &(array[42]), which is going to cause all sorts of havoc to your processing loops.


The C++ standard guarantees that the size of any class is at least one. The C++ standard states that no object shall have the same memory address as another object. There are several good reasons for this.

  1. To guarantee that new will always return a pointer to a distinct memory address.
  2. To avoid some divisions by zero. For instance, pointer arithmetics (many of which done automatically by the compiler) involve dividing by sizeof(T).

sizeof 测试

来源:geeksforgeeks

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Empty {
};

class Derived1 : public Empty {
};

class Derived2 : virtual public Empty {
};

class Derived3 : public Empty {
char c;
};

class Derived4 : virtual public Empty {
char c;
};

class Dummy {
char c;
};

大小分别是:1,1,8,1,16,1

原因:

  • 一个类中,虚函数本身、成员函数(包括静态与非静态)和静态数据成员都是不占用类对象的存储空间
  • 类中声明了虚函数(不管是1个还是多个),那么在实例化对象时,编译器会自动在对象里安插一个指针vPtr指向虚函数表VTable
  • 虚继承:涉及到虚函数表和虚基表,会增加一个vfPtr指针指向虚函数表vfTable(多重虚继承下对应多个);一个vbPtr指针指向虚基表vbTable,这两者所占的空间大小为:8(或8乘以多继承时父类的个数)
  • 内存对齐

总结:

  1. 让任意两个对象的内存不同
  2. 标准规定,实现保证
  3. 能保证new出来的都是独一无二的地址
  4. 能保证某些宏内的计算数组大小的算法:#define ARRAY_SIZE((A)) sizeof((A)) / sizeof((A[0]))不会出现除数为0的错误

Ref

https://www.geeksforgeeks.org/why-is-the-size-of-an-empty-class-not-zero-in-c/

https://stackoverflow.com/questions/2362097/why-is-the-size-of-an-empty-class-in-c-not-zero

https://stackoverflow.com/questions/621616/c-what-is-the-size-of-an-object-of-an-empty-class

https://blog.csdn.net/qq_22203741/article/details/106797215

该图片由Mariya 🌸🌺🌼Pixabay上发布


C++空类大小的探讨
https://blogoasis.github.io/post/347fef97.html
作者
phInTJ
发布于
2022年10月28日
许可协议