92

可能重复:
C++:空类的对象的大小是多少?

为什么会出现以下输出1

#include <iostream>

class Test
{
};

int main()
{
    std::cout << sizeof(Test);
    return 0;
}
4

5 回答 5

132

该标准不允许大小为 0 的对象(及其类),因为这会使两个不同的对象具有相同的内存地址成为可能。这就是为什么即使是空类也必须具有(至少)1 的大小。

于 2010-03-02T09:36:21.663 回答
38

保证两个不同对象的地址会不同。出于同样的原因,“new”总是返回指向不同对象的指针。

有关完整答案,请参见Stroustrup

于 2010-03-02T09:37:32.413 回答
30

C++ 标准保证任何类的大小至少为 1。C++ 标准规定,任何对象都不得与另一个对象具有相同的内存地址。这有几个很好的理由。

  1. 以保证new将始终返回指向不同内存地址的指针。

  2. 避免一些除以零。例如,指针算术(其中许多由编译器自动完成)涉及除以sizeof(T).

但是请注意,这并不意味着空基类会将派生类的大小加 1:

struct Empty { };

struct Optimized : public Empty {
    char c;
};

// sizeof(Optimized) == 1 with g++ 4.0.1

Bjarne Stroustrup 也谈到了这一点。

于 2010-03-02T09:51:38.907 回答
13

没有任何数据成员和成员函数的类,这种类型的类称为空类。空类对象的大小始终为 1 个字节。

当我们当时创建任何类的对象时,对象总是具有 3 个特征,即

  1. 状态
  2. 行为
  3. 身份

当我们创建空类的对象时,那个对象的状态是什么。该对象的行为也没什么,但是编译器为该对象分配了一个唯一的地址。计算机中的内存始终以字节的形式组织,对象地址位置的最小可用内存为 1 个字节。这就是为什么空类对象的大小是 1 个字节的原因。

于 2011-10-17T07:55:50.890 回答
4

Maurits 和 Péter 所说的。

有趣的是,在这种情况下,编译器可以进行空基类优化(EBCO):

#include <iostream>
struct Foo {};
struct Bar : Foo {};
int main () {
    std::cout << sizeof(Foo) << ',' << sizeof(Bar) << std::endl;        
}

如果您编译并运行它,这可能会打印“1,1”。另见关于 EBCO 的Vandevoorde/Josuttis 16.2 。

于 2010-03-02T09:54:52.817 回答