首页 > C++编程 > 又是C++空类

又是C++空类

之前在博客也写过一些空类相关的文章,记得当时候还有一个问题没有想明白,于是在经过了一番思索。空类问题似乎也是面试中经常涉及的问题,还是先看题目吧:

// Author: 代码疯子
// Blog: http://www.programlife.net/
// C++空类以及sizeof问题
#include <iostream>
using namespace std;
 
class Empty
{
public:
	char arr[0];
};
 
int main(int argc, char **argv)
{
	printf("%d\n", sizeof(Empty));
	// Empty em[10];
	return 0;
}

这里输出到底是多少呢?大部分或许会说是1。恩,试一试就知道了。在MS VC++环境下,确实输出是1.不过还会看到一个警告:
1>e:\2011\XXXX\probs\vs\ec.cpp(7) : warning C4200: 使用了非标准扩展 : 结构/联合中的零大小数组
1> 当 UDT 包含大小为零的数组时,无法生成复制构造函数或副本赋值运算符

如果硬是要把上面那个定义对象数组的注释去掉,那么VS就要怒了:
e:\2011\XXXX\probs\vs\ec.cpp(13) : error C2233: “em”: 包含大小为零的数组的对象数组是非法的

提示错误C2233,不能定义大小为0的数组。接下来试一试GCC吧(这里的版本是gcc (GCC) 3.4.2 (mingw-special))。GCC竟然输出的是0,而且可以定义后面那个Empty em[10],可以看出这个版本的编译器的实现还是不太好。改一下代码试试:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// Author: 代码疯子
// Blog: http://www.programlife.net/
// C++空类以及sizeof问题
#include <iostream>
using namespace std;
 
class Empty
{
public:
	char arr[0];
};
 
int main(int argc, char **argv)
{
	// printf("%d\n", sizeof(Empty));
	Empty em[10];
	if (&em[0] == &em[2])
	{
		printf("Oops! This compiler appears to be crazy!\n");
	}
	else
	{
		printf("Just OK!\n");
	}
 
	for (int i = 0; i < 10; ++i)
	{
		printf("&em[%d] = 0x%08X\n", i, &em[i]);
	}
 
	return 0;
}

可以看到数组成员的地址都是一样的,这就给人不太好的印象了。

GCC编译器对C++空类的测试

相关文章:
C++空类sizeof字节数
C++空类sizeof字节数(二)
再谈面试中的sizeof
空白基类最优化 The Empty Base Class Optimization (EBCO)

弄了这么多,我觉得这个问题就没有必要再深究了……懂得编译器对空类的优化基址,懂得不同的编译器结果可能不一样就行。


觉得文章还不错?点击此处对作者进行打赏!


本文地址: 程序人生 >> 又是C++空类
作者:代码疯子(Wins0n) 本站内容如无声明均属原创,转载请保留作者信息与原文链接,谢谢!


更多



分类: C++编程 标签: , , ,
  1. 2011年5月6日17:28 | #1

    RSS怎么不是全文了

    [回复]

  2. 2011年5月6日23:45 | #2

    同上,rss怎么不是全文了?不过还是直接来你的站看文章

    [回复]

  3. 2011年5月7日12:53 | #3

    @JayXon
    失误,RSS全文输出已经恢复,谢谢你的关注,希望我的文字能给你带来有用的东西O(∩_∩)O~

    [回复]

  4. 2011年5月7日12:54 | #4

    @阿拉丁
    哈哈,看哪个方便吧。RSS全文输出已经恢复了。博客速度可能有点卡,理论上来说RSS更加方便

    [回复]

  5. pestu
    2011年5月15日23:10 | #5

    如果再加一个纯虚函数,情况又不一样了。
    virtual myadd(int x) = 0;

    [回复]

  6. 2011年5月15日23:13 | #6

    @pestu
    是不是会加一个vptr进来?

    [回复]

  7. pestu
    2011年5月15日23:22 | #7

    @代码疯子
    是啊。。有了虚函数表了

    [回复]

  8. 2011年5月15日23:25 | #8

    @pestu
    底层《深度探索C++对象模型》讲的很细。看了前面几章

    [回复]