我知道C++中的空类大小为1个字节.但是,我注意到sizeof()为此类的对象返回0(以g ++为单位):
class Boom{
int n[0];
}
Run Code Online (Sandbox Code Playgroud)
我可以为Boom对象打印有效的内存位置:
Boom b;
cout<<&b;
Run Code Online (Sandbox Code Playgroud)
这个特定的内存位置是否占用?如果我稍后在程序中分配内存,是否有可能使用此位置?
数组的大小不能为零.如果您的编译器允许您声明一个,那么该语言不会指定它的行为方式.
在这种情况下,使用此编译器,确实看起来这允许两个对象占据相同的位置:
Boom b[2];
std::cout << &b[0] << ' ' << &b[1] << std::endl;
// Output: 0x7fffffb23fdc 0x7fffffb23fdc
Run Code Online (Sandbox Code Playgroud)
但是其他编译器可能表现不同,或者只是拒绝无效声明(如果你指定GCC会这样做-pedantic -Werror).
对于类和数组,大小为0都是无效的.C++标准说:
Sizeof [expr.sizeof]
[...]最派生类的大小应大于零[...]
和
数组[dcl.array]
在TD的声明中,D表格
Run Code Online (Sandbox Code Playgroud)D1 [ constant-expressionopt] attribute-specifier-seqopt[...]如果存在常量表达式(5.19),它应该是一个整数常量表达式,其值应大于零[...]
如果您-pedantic使用g ++ 打开,您将收到以下警告(或错误pedantic-errors):
ISO C++ forbids zero-size array ‘n’
Run Code Online (Sandbox Code Playgroud)
因此,您的程序基本上无效,但可以通过C++标准的编译器扩展进行编译(除非您关闭此扩展).
注意:即使你的编译器可以报告0的class,也不会为任何实例(又名对象)这样做class:
#include <iostream>
class Boom {
int n[0];
};
int main() {
std::cout << sizeof(Boom) << '\n'; // prints 0
std::cout << sizeof(Boom()) << '\n'; // prints 1
}
Run Code Online (Sandbox Code Playgroud)
具有大小为0的对象将远离标准.
为什么空类的大小不为零?
确保两个不同对象的地址不同.出于同样的原因,"new"总是返回指向不同对象的指针.考虑:
Run Code Online (Sandbox Code Playgroud)class Empty { }; void f() { Empty a, b; if (&a == &b) cout << "impossible: report error to compiler supplier"; Empty* p1 = new Empty; Empty* p2 = new Empty; if (p1 == p2) cout << "impossible: report error to compiler supplier"; }有一条有趣的规则表明空基类不需要用单独的字节表示:
Run Code Online (Sandbox Code Playgroud)struct X : Empty { int a; // ... }; void f(X* p) { void* p1 = p; void* p2 = &p->a; if (p1 == p2) cout << "nice: good optimizer"; }这种优化是安全的,并且是最有用的.它允许程序员使用空类来表示非常简单的概念而不会产生开销.一些当前的编译器提供了这种"空基类优化".
| 归档时间: |
|
| 查看次数: |
220 次 |
| 最近记录: |