C ++:空类对象的大小是多少?

时间:2009-03-07 10:06:50

标签: c++ class object

我想知道什么是空类对象的大小。它肯定是0字节,因为它应该可以像任何其他对象一样引用和指向它。但是,这样的对象有多大?

我使用了这个小程序:

#include <iostream>
using namespace std;

class Empty {};

int main()
{
    Empty e;
    cerr << sizeof(e) << endl;
    return 0;
}

我在Visual C ++和Cygwin-g ++编译器上得到的输出是 1字节!这对我来说有点令人惊讶,因为我期望它的机器字大小(32位或4字节)。

任何人都可以解释为什么 1个字节的大小? 为什么不 4个字节?这是依赖于编译器还是机器?此外,有人可以给出一个更有说服力的理由,说明为什么空类对象不会大小为0字节?

17 个答案:

答案 0 :(得分:118)

引用Bjarne Stroustrup's C++ Style and Technique FAQ,大小非零的原因是“确保两个不同对象的地址不同。”并且大小可以是1,因为这里的对齐并不重要,因为实际上没有什么可以看。

答案 1 :(得分:30)

标准规定所有派生的对象都有sizeof()&gt; = 1:

  

除非它是位字段(class.bit),否则大多数派生对象应具有非零大小并且应占用一个或多个存储字节。基类子对象可以具有零大小。   ISO/IEC FDIS 14882:1998(E) intro.object

答案 2 :(得分:12)

这真的是一个实现细节。很久以前,我认为它可能是零字节或一千字节,它与语言规范无关。但是,在查看标准(第5.3.3节)后,sizeof被定义为总是返回一个或多个,无论如何。

  

派生程度最高的类的大小应大于零。

除其他外,这是允许您处理对象数组和指向它们的指针所必需的。如果允许您的元素为零,那么&(array[0])将与&(array[42])相同,这将对您的处理循环造成各种各样的破坏。

它可能不是机器字的原因是它内部没有实际要求它在字边界上对齐的元素(例如整数)。例如,如果将char x; int y;放在类中,我的GCC会将其计时为8个字节(因为第二个int必须在该实现中对齐)。

答案 3 :(得分:6)

有一个例外:0长度数组

#include <iostream>

class CompletlyEmpty {
  char NO_DATA[0];
};

int main(int argc, const char** argv) {
  std::cout << sizeof(CompletlyEmpty) << '\n';
}

答案 4 :(得分:5)

即使不需要为空类分配任何内存,但为了使空类的对象成为可能,编译器会分配可分配的最小内存,即1字节。这样编译器就可以唯一地区分同一个空类的两个对象,并且能够将对象的地址分配给空类类型的指针。

答案 5 :(得分:4)

我认为链接到解释这个好处的答案可能会有所帮助。关于It is boost::compressed_pair Logan Capaldo {{3}}。

答案 6 :(得分:3)

这可能有助于你:-) http://bytes.com/topic/c/insights/660463-sizeof-empty-class-structure-1-a

  

空类或结构的大小为1

     

发生这种情况的原因归结为正确实施   标准,C ++标准所说的一件事是“没有对象   在内存中应具有与任何其他变量相同的地址“......什么   确保这是最简单的方法吗?确保所有类型都有   非零尺寸。为了实现这一点,编译器添加一个虚拟字节   没有数据成员且没有虚拟成员的结构和类   函数使它们的大小为1而不是大小为0和   然后他们保证有一个唯一的内存地址。

答案 7 :(得分:2)

没有数据成员但是大小为1字节的类的原因是此* 强文本 *必须存储在内存中,以便引用或指针可以指向该类的对象

答案 8 :(得分:2)

空类的1字节分配取决于编译器。编译器需要确保对象驻留在不同的内存位置,并且需要为对象分配非零内存大小。 在此处收听有关此主题的说明:http://listenvoice.com/listenVoiceNote.aspx?id=27

即使编译器将非零大小分配给空类,它们也会在从空类派生新类时进行优化。 听听ListenVoice的c ++编程面试问题的空基优化。

答案 9 :(得分:0)

空类 - 该类不包含任何内容。

任何非空的类都将由其在内存中的内容表示。

现在如何在内存中表示空类? 因为它没有任何内容无法显示其在记忆中的存在,但是类存在,必须在内存中显示它的存在。 要在内存中显示空类,需要1个字节。

答案 10 :(得分:0)

我认为是这样的,因为1个字节是可以用作占位符的最小内存单元,并且它不能给出零大小,因为无法创建对象数组。

和你所说的东西&#34;这对我来说有点令人惊讶,因为我期望它的机器字大小(32位或4字节)。&#34;对于类型为empty()的引用变量(macine词),而不是类本身的大小(这是抽象数据类型),将为true,

答案 11 :(得分:0)

我认为这个问题只是理论上的兴趣,但在实践中并不重要。

正如其他人已经指出的那样,从空类派生并没有造成任何伤害,因为这不会为基类部分消耗任何额外的内存。

此外,如果一个类是空的(意味着它 - 理论上 - 不需要任何每个实例的内存,即它没有任何非静态数据成员或虚拟成员函数)那么所有它的成员函数也可以(并且应该)定义为static。所以没有必要创建这个类的实例。

底线:如果您发现自己编写了一个空类X,那么只需将所有成员函数设置为静态。然后,您不再需要创建X对象,派生类也不会受到任何影响。

答案 12 :(得分:0)

#include<iostream>
using namespace std;


    class Empty { };
    int main()
    {
        Empty* e1 = new Empty;
        Empty* e2 = new Empty;

        if (e1 == e2)
            cout << "Alas same address of two objects" << endl;
        else
            cout << "Okay it's Fine to have different addresses" << endl;

        return 0;
    }

输出:好的,有不同的地址

返回大小1可确保两个对象不具有相同的地址。

答案 13 :(得分:0)

确保两个不同的对象具有不同的地址是非零的。 不同的对象应该有不同的地址,因此空类的大小总是1个字节。

答案 14 :(得分:-1)

对于一个空类的对象,编译器分配1个字节用于唯一地址标识。所以,如果一个类有多个对象,它们可以有不同的唯一内存位置。假设,如果一个类没有任何大小,那么内存位置会存储什么?这就是为什么我们在 C++ 程序中创建一个空类的对象时,它需要一些内存来存储,并且可以保留的最小内存量为 1 个字节。所以,如果我们创建一个空类的多个对象,每个对象都会有一个唯一的地址。

在 C++ 代码示例下方,将始终为两个对象提供唯一地址,为空类 EmptyClass 创建。

int main()
{
    EmptyClass obj1;
    EmptyClass obj2;
     
    if (&obj1 == &obj2){
         cout << "Both objects have same address" << endl;
    }else{
        cout << "Both objects have unique address" << endl;
    }       
    return 0;
}

答案 15 :(得分:-2)

我认为如果空类的大小为零,则意味着它不存在。要使它(类)存在,它需要至少有1个字节,因为这个字节是内存/引用地址。

答案 16 :(得分:-3)

这是因为这个指针,虽然指针是4字节的(整数)但它引用 到1个字节的一个存储单元(一个单元)。