Why is the size of an empty class not zero in C++?
Predict the output of the following program?
1 #include<iostream>
2 using namespace std;
3
4 class Empty
5 {
6 };
7
8 int main()
9 {
10 cout << sizeof(Empty) << endl;
11 return 0;
12 }
Output: 1
Size of an empty class is not zero. It is 1 byte generally. It is non-zero to ensure that the two different objects will have different addresses.
See the following example.
1 #include<iostream>
2 using namespace std;
3
4 class Empty
5 {
6 };
7
8 int main()
9 {
10 Empty a, b;
11
12 if (&a == &b)
13 {
14 cout << "impossible " << endl;
15 }
16 else
17 {
18 cout << "Fine " << endl;
19 }
20
21 return 0;
22 }
Output: Fine
For the same reason (different objects should have different addresses), “new” always returns pointers to distinct objects.
See the following example.
1 #include<iostream>
2 using namespace std;
3
4 class Empty
5 {
6 };
7
8 int main()
9 {
10 Empty* p1 = new Empty;
11 Empty* p2 = new Empty;
12
13 if (p1 == p2)
14 {
15 cout << "impossible " << endl;
16 }
17 else
18 {
19 cout << "Fine " << endl;
20 }
21 return 0;
22 }
Output: Fine
Now guess the output of following program (This is tricky).
1 #include<iostream>
2 using namespace std;
3
4 class Empty
5 {
6 };
7
8 class Derived: Empty
9 {
10 int a;
11 };
12
13 int main()
14 {
15 cout << sizeof(Derived);
16 return 0;
17 }
Output (with GCC compiler): 4
Note that the output is not greater than 4. There is an interesting rule that says that an empty base class need not be represented by a separate byte. So compilers are free to make optimization in case of empty base classes.
As an excercise, try the following program on your compiler.
1 #include <iostream>
2 using namespace std;
3
4 class Empty
5 {
6 };
7
8 class Derived1 : public Empty
9 {
10 };
11
12 class Derived2 : virtual public Empty
13 {
14 };
15
16 class Derived3 : public Empty
17 {
18 char c;
19 };
20
21 class Derived4 : virtual public Empty
22 {
23 char c;
24 };
25
26 class Dummy
27 {
28 char c;
29 };
30
31 int main()
32 {
33 cout << "sizeof(Empty) " << sizeof(Empty) << endl;
34 cout << "sizeof(Derived1) " << sizeof(Derived1) << endl;
35 cout << "sizeof(Derived2) " << sizeof(Derived2) << endl;
36 cout << "sizeof(Derived3) " << sizeof(Derived3) << endl;
37 cout << "sizeof(Derived4) " << sizeof(Derived4) << endl;
38 cout << "sizeof(Dummy) " << sizeof(Dummy) << endl;
39
40 return 0;
41 }
运行结果如下所示。
补充:
运行如下代码,运行结果为: 1
1 #include <cstdio>
2 #include <iostream>
3 using namespace std;
4 class Test
5 {
6 int arr[0];
7 };
8
9 int main()
10 {
11 Test t;
12 cout<<sizeof(t);
13 return 0;
14 }
Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.
转载请注明:http://www.cnblogs.com/iloveyouforever/
2013-11-25 20:39:10
Why is the size of an empty class not zero in C++?的更多相关文章
- [转载] C++ STL中判断list为空,size()==0和empty()有什么区别
关于两个的区别,首先size()==0为bool表达式,empty()为函数调用,这一点很明显.查看源代码, bool empty() const { return _M_node->_M_ne ...
- 数据结构:队列queue 函数push() pop size empty front back
队列queue: push() pop() size() empty() front() back() push() 队列中由于是先进先出,push即在队尾插入一个元素,如:可以输出:Hello W ...
- 空基类优化empty base class optimization
1.为什么C++中不允许类的大小是0 class ZeroSizeT {}; ZeroSizeT z[10]; &z[i] - &z[j]; 一般是用两个地址之间的字节数除以类型大小而 ...
- [LeetCode] Implement Queue using Stacks 用栈来实现队列
Implement the following operations of a queue using stacks. push(x) -- Push element x to the back of ...
- [LeetCode] Implement Stack using Queues 用队列来实现栈
Implement the following operations of a stack using queues. push(x) -- Push element x onto stack. po ...
- [LeetCode] House Robber II 打家劫舍之二
Note: This is an extension of House Robber. After robbing those houses on that street, the thief has ...
- [LeetCode] House Robber 打家劫舍
You are a professional robber planning to rob houses along a street. Each house has a certain amount ...
- leetcode笔记
82. Remove Duplicates from Sorted List II https://leetcode.com/problems/remove-duplicates-from-sorte ...
- Maximal Rectangle
很不好想的一道题,参考:http://blog.csdn.net/doc_sgl/article/details/11832965 分为两步:把原矩阵转为直方图,再用largest rectangle ...
随机推荐
- mongodb安装教程(一)
版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/fengtingYan/article/de ...
- webpack 提取css成单独文件
webpack 提取css成单独文件 // 用来拼接绝对路径的方法 const {resolve} = require('path') const HtmlWebpackPlugin = requir ...
- OpenXml SDK学习笔记(1):Word的基本结构
能写多少篇我就不确定了,可能就这一篇就太监了,也有可能会写不少. OpenXml SDK 相信很多人都不陌生,这个就是管Office一家的文档格式,Word, Excel, PowerPoint等都用 ...
- 『学了就忘』Linux基础命令 — 37、Linux中挂载操作的相关命令
目录 1.mount命令介绍 (1)mount命令说明 (2)mount命令格式 2.mount命令示例 3.mount -a命令说明 4.-o特殊选项说明 5.exec/noexec选项说明 挂载就 ...
- 【JAVA】笔记(3)---封装;如何选择声明静态变量还是实例变量;如何选择声明静态方法还是实例方法;静态代码块与实例代码块的执行顺序与用途;
封装: 1.目的:保证对象中的实例变量无法随意修改/访问,只能通过我们自己设定的入口,出口(set / get)来间接操作:屏蔽类中复杂的结构,使我们程序员在主方法中关联对象写代码时,思路/代码格式更 ...
- zookeeper问题在公司可以 回到家用家里网不行 目前还没有解决
Opening socket connection to server 192.168.1.193/192.168.1.193:2181. Will not attempt to authentica ...
- Java 处理表格,真的很爽!
一个简单又快速的表格处理库 大家好,我是鱼皮. 处理 Excel 表格是开发中经常遇到的需求,比如表格合并.筛选表格中的某些行列.修改单元格数据等. 今天给大家分享一个 Java 处理表格的工具库,不 ...
- .NET Core中的鉴权授权正确方式(.NET5)
一.简介 前后端分离的站点一般都会用jwt或IdentityServer4之类的生成token的方式进行登录鉴权.这里要说的是小项目没有做前后端分离的时站点登录授权的正确方式. 一.传统的授权方式 这 ...
- Python技法1:变长和定长序列拆分
Python中的任何序列(可迭代的对象)都可以通过赋值操作进行拆分,包括但不限于元组.列表.字符串.文件.迭代器.生成器等. 元组拆分 元组拆分是最为常见的一种拆分,示例如下: p = (4, 5) ...
- Atcoder Regular Contest 123 题解
u1s1 我是真的不知道为什么现场这么多人切了 D,感觉 D 对思维要求显然要高于其他 300+ 人切掉的 D 吧(也有可能是 Atc 用户整体水平提升了?) A 开 幕 雷 击(这题似乎 wjz 交 ...