空基类优化

fre*_*low 9 c++

来自C++标准的两个引用,§1.8:

对象是存储区域.

基类子对象可以具有零大小.

我不认为存储区域的大小为零.这意味着某些基类子对象实际上不是对象.这些陈述如何共存?

Ash*_*ain 10

C++不允许大小为零的对象,因为每个对象必须具有唯一的内存地址.所以如果你有:

struct empty {};

// ...

empty myempty;
empty* ptr = &myempty;
Run Code Online (Sandbox Code Playgroud)

然后ptr必须指向一个唯一的内存地址.标准规定对象的最小大小为1个字节.类似地,允许大小为0的分配,并返回有效指针,即使不允许写入该指针(这适用于malloc(0),并new empty返回指向一个字节的指针,因为sizeof(empty) == 1).

如果我empty是这样的:

struct derived : public empty
{
    int data;
}
Run Code Online (Sandbox Code Playgroud)

基类中不再有任何empty占用一个字节的点,因为所有成员derived都会有一个唯一的地址data.在这种情况下,引用"基类子对象可以具有零大小"以允许编译器不使用任何空间empty,例如sizeof(derived) == 4.正如标题所述,它只是一种优化,并且占据零空间的empty部分是完全合法的derived.


Ste*_*sop 10

关于"地区"定义的哲学论证是不必要的.

1.8/5说,"除非它是一个位字段,否则大多数派生对象的大小应为非零......基类子对象的大小可能为零".

所以标准很清楚什么对象(以及因此"存储区域")可以具有零大小.如果您不同意标准"英语区域"在英语中的含义,那么您可以错误地解释作者(非编程相关)的文学技巧.对于这个问题,你可以错过他们的诗歌技巧(14.7.3/7)但是很清楚标准在这里所说的关于类类型的对象的大小.

阅读标准的实用方法是,对一个单词进行两种似是而非的解释,选择一个与标准的同一部分中的另一个句子不直接相矛盾的解释.不要选择与您个人首选使用的词语更匹配的词汇,甚至是最常用的词汇.