2012-02-06 60 views
9

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

回答

11

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

classstruct必须有其sizeof0更大,ERGO你的行为。这是标准预期和要求的。

+0

其实在g ++中,可以定义一个具有0大小的类。看到我的答案。 – TrueY 2016-07-07 07:42:15

0

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

2

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

3

该字节不包含任何内容,它在那里使某些其他行为更好。例如,考虑另一个包含空类的情况。

class Empty 
{ }; 

class TwoEmpties 
{ 
    Empty a; 
    Empty b; 
}; 

您可能希望两个成员,&TwoEmpties::a&TwoEmpties::b,的地址是不同的。要发生这种情况,它们必须具有大于1的大小(或者编译器必须在它们之间添加填充,这又会使编译器何时何地向编译器添加填充的规则复杂化。)

+0

不可否认**你经常需要两位成员的地址。的确,在大多数情况下,你不关心两位成员的地址。这条规则适用于少数用例,虽然它们被认为足够重要,可以授权它。 – 2012-02-06 09:13:51

+0

@MatthieuM。同意。修正了这个措辞 – 2012-02-06 09:35:41

7

它是强制的根据标准,相同类型的不同对象应该具有不同的地址。这又确保对于任何对象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的谓词。

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,以防止这种情况发生。

0

根据我的知识,上述所有答案都不正确。 正确答案是默认创建的类的对象时,4个内置函数被调用是

  1. 默认的构造

  2. 默认析构函数

  3. 复制构造

  4. 重载作业运营商

因此空类的大小是1字节, 示例:尝试这个

#include<iostream> 
using namespace std; 
class Test 
{ 
}; 
int main() 
{ 
Test t; 
cout<< "size of empty class is "<<sizeof(t); 
} 
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的堆上分配了一个新的非零大小的类,则返回一个有效的地址,并且如果多次分配它们的指针指向不同的内存地址。

+0

好吧,一个静态的零长度数组是不合格的。 – Deduplicator 2017-07-04 22:50:41

+0

@Deduplicator也许你是对的,但我已经看到过这样的结构(char [0]作为最后一项)。所以它以某种方式传播。 – TrueY 2017-07-06 08:11:49

+0

struct int {int} length; char d [0]; }; 是变量记录长度*技巧*(尽管我不喜欢调用任何如此强大的'技巧':))。 – 2017-09-16 14:16:08