C ++类空类大小为1个字节

时间:2012-02-06 07:57:08

标签: c++ sizeof

我是C ++的新手,在C ++中发现了一个特殊的功能。我看到一个空的大小是1个字节,我做了一些研究,发现这是完成的,因为每个对象必须有一个不同的地址。但是我想知道放置的那个1字节的内容是什么。我知道它不会持有“this”指针,但它是一个虚拟字节还是实际上有一些内容?

8 个答案:

答案 0 :(得分:11)

没有内容。它只是一个虚拟字节。

每个classstruct必须使其sizeof大于0,这样才能行事。它是标准的预期和强制要求。

答案 1 :(得分:8)

标准强制要求相同类型的不同对象具有不同的地址。这反过来确保对于任何对象TT*充当此对象的明确标识符(对于此类型)。

当然,您通常不需要知道两个对象是否真的相同,但有时(给定C ++低级访问)这是必要的或者只是简单方便。

因此指定没有对象应该具有空值。

此规则有一个例外:当使用空类作为基类时,编译器可能会选择应用空基优化 EBO )是某些情况,例如:

struct Empty {};

struct Slim: Empty {
  int a;
};

static_assert(sizeof(Slim) == sizeof(int), "");

通常会添加基类的大小,但在这种特殊情况下,它不是必需的。但是,相同类型的两个不同对象永远不应该具有相同地址的规则仍然适用,因此:

struct Fat: Empty {
  Empty e;
};

static_assert(sizeof(Fat) > sizeof(Empty), "");

EBO 是在模板情况下使用private继承的主要原因。例如:

template <typename Allocator>
class MyClass: private Allocator {
};

这样,如果事实证明Allocator是一个空类,那么就不会有任何开销。通常,它通常用于策略,例如您传递给map的谓词。

答案 2 :(得分:3)

该字节不包含任何东西,它可以使某些其他行为更好。 例如,考虑另一个包含空类的情况。

class Empty
{ };

class TwoEmpties
{
  Empty a;
  Empty b;
};

您可能希望两个成员&TwoEmpties::a&TwoEmpties::b的地址不同。要做到这一点,他们的大小必须> 1.(或者编译器必须在它们之间添加填充,这反过来会使编译器在何时何地向类添加填充的规则变得复杂。)

答案 3 :(得分:2)

您可以使用调试器或类似printf("%x", *(unsigned char *)&myobj);的简单内容来查看字节的内容。我还没有读过C ++规范,但我会猜测字节的内容是未定义的,所以行为取决于编译器和你的操作系统。

答案 4 :(得分:1)

empty class has a sizeof 1因为当创建该类的对象时,如果size = 0,它们将存储在内存中的相同位置。

假设您在创建对象时address is 1000

如果class is 0的大小也是object must be 0的大小。

(therefore, object is located at 1000+0=1000)

现在如果有另一个对象,

Add. of 2nd object=1000+0th location

两个对象都具有相同的地址,这是未定义的行为,不应该出现,因为对象被引用会有歧义。

因此empty classes are given a byte of memory可以防止这种情况发生。

答案 5 :(得分:0)

这是一个虚拟字节 - 构造函数和析构函数将是微不足道的,没有“数据存储”。

答案 6 :(得分:0)

根据我的知识,以上所有答案都是不对的。 默认情况下,正确的答案是在创建类的对象

时调用4个内置函数
  1. 默认构造函数

  2. 默认析构函数

  3. 复制构造函数

  4. 重载分配运算符

  5. 因此空类的大小是1byte, 示例:试试这个

    #include<iostream>
    using namespace std;
    class Test
    {
    };
    int main()
    {
    Test t;
    cout<< "size of empty class is "<<sizeof(t);
    }
    

答案 7 :(得分:0)

我面临类似的问题,似乎可以用一个小技巧定义一个零长度的类。我不知道是不是因为g ++,而是看下面的代码片段:

struct ONE {};
struct ZERO { char x[0]; };

int main() {
  cout << sizeof(ONE) << ", " << sizeof(ZERO) << endl;

  ONE* po1 = new ONE;
  ONE* po2 = new ONE;
  cout << po1 << ", " << po2 << endl;

  ZERO* pz1 = new ZERO;
  ZERO* pz2 = new ZERO;
  cout << pz1 << ", " << pz2 << endl;
}

输出结果为:

1, 0
0xe4f010, 0xe4f030
0xe4f050, 0xe4f070

所以空类的大小是一(根据C ++标准),但如果它只有一个零长度数组字段,则大小变为零。如果在具有new的堆上分配了一个新的真正零大小的类,则返回一个有效地址,如果多次分配它们的指针指向不同的内存地址。