为什么基类的大小为零?

时间:2010-10-12 10:36:26

标签: c++

基本上它是this question跟进 ..

当我查看标准文档时,我发现了这个..

类9.3

  

类类型的完整对象和成员子对象应具有非零大小。 96) ...

是的,是的..但是,

  

96)基类子对象不受约束

所以,当我查看Stroustrup's FAQ时,有一个例子为

void f(X* p)
    {
        void* p1 = p;
        void* p2 = &p->a;
        if (p1 == p2) cout << "nice: good optimizer";
    } 

我的问题是我无法理解如何进行优化以及为什么基类允许零大小

5 个答案:

答案 0 :(得分:11)

基类 不能 的大小为零。只有基类 子对象 才可以。表示派生对象的基本部分。

答案 1 :(得分:10)

如果基类为空,则永远不需要拥有基类对象或其任何成员的地址(独立于派生类对象的地址),因此优化其大小是合法的。

这可以节省你(至少)一个字节的内存(可能更多是由于内存对齐规则),如果你的应用程序在内存受限的平台上有数百万个这样的对象,这可以大大节省成本。 / p>

答案 2 :(得分:0)

我不是雷蒙德·陈,但我可以玩'如果它是真的'游戏。

如果可以作为引用传递的类可以是零大小,那么在某些时候它可能会传递给malloc(0),这可能会返回NULL或不可解析的地址。然后两个实例在不应该的时候看起来相等。

如果它是另一个类或基类的成员,它的地址和大小是从它在包含类分配中的位置得出的,并且它的大小是安全的。

零大小有助于提高内存效率。

答案 3 :(得分:0)

这是一种优化,因为如果基类子对象需要具有非零大小,则派生类的实例占用的空间比它们所占用的空间少。这意味着基类(如接口,混合或模板化策略类)不会增加实现或使用它们的类的大小。最终,你的程序需要更少的内存来做同样的事情。

我对历史并不十分肯定,但我得到的印象是,在20世纪90年代的某个时候,一些编制者开始这样做,标准委员会决定将现有做法标准化。我认为STL模板中分配器对象的增加是原因的一部分 - std::vector通常是具有空基优化的3个指针的大小,而没有它的4个指针(由于对齐)。 Here's an article从1997年开始讨论它 - 很明显,当它写成时并不是那么普遍,但它现在基本上是标准的做法。

答案 4 :(得分:0)

对象的大小只不过是其成员的累积大小。 并且不,没有类可以具有零大小,即使空类也将具有1字节的大小。

这里的意思是

Base class subobjects are not so constrained.

是对象本身不会消耗任何空间而不是它的成员。因此,对象的地址可能与其第一个成员子对象的地址匹配,与arrays的情况相同。那就是优化。

在派生类的情况下,它必然包括基类对象,即使为空也会消耗1个字节,因此上面的优化对派生类无效。