空类的大小

hatlonely · · 171 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。
空类就是没有任何数据成员的类,这种类占用的内存大小在不同的语言里面有不同的实现 ## c ``` c++ struct A {}; printf("sizeof(A): %lu\n", sizeof(struct A)); // sizeof(A): 0 ``` 这个结果输出是0,也就是说 c 语言中的空类大小为 0 ``` c++ struct A a1; struct A a2; printf("address(a1): %p\n", &a1); printf("address(a2): %p\n", &a2); printf("&a1 == &a2: %d\n", &a1 == &a2); // address(a1): 0x7ffdead15ff0 // address(a2): 0x7ffdead15ff0 // &a1 == &a2: 0 ``` 在 gcc 中,两个空类拥有相同的地址,但是比较的结果却是不同的……这个我也不知道咋解释…… ## c++ ``` c++ class A {}; std::cout << "sizeof(A): " << sizeof(A) << std::endl; // sizeof(A): 1 ``` c++ 的空类大小为1,因为 c++ 中规定不同的对象必须拥有不同的地址,如果为0会导致两个空类的地址一样 ``` c++ class B { A a1; A a2; }; std::cout << "sizeof(B): " << sizeof(B) << std::endl; // sizeof(B): 2 ``` 空类作为成员,按照大小为 1 来处理 ``` c++ class C : public A {}; std::cout << "sizeof(C): " << sizeof(C) << std::endl; // sizeof(C): 1 class D : public A { int i; }; std::cout << "sizeof(D): " << sizeof(D) << std::endl; // sizeof(D): 4 ``` 基类为空类不占空间,这个就是空白基类优化 EBO (empty base optimization) ## golang ``` go type A struct{} fmt.Println("sizeof(A):", unsafe.Sizeof(A{})) // sizeof(A): 0 ``` golang 中空类的大小为 0 ``` go a1 := A{} a2 := A{} fmt.Printf("a1 == a2: %v\n", &a1 == &a2) // a1 == a2: false ``` 两个空类对象在栈上拥有不同的地址 ``` go a3 := A{} a4 := A{} fmt.Printf("address(a3): %p\n", &a3) // a3 逃逸到堆区 fmt.Printf("address(a4): %p\n", &a4) // a4 逃逸到堆区 fmt.Printf("a3 == a4: %v\n", &a3 == &a4) // address(a3): 0x1190fd0 // address(a4): 0x1190fd0 // a3 == a4: true ``` 调用 printf,a3、a4 逃逸到了堆区,在堆区拥有相同的地址 这个地方确实很怪,仅仅因为调用了一次 printf,导致 `&a1 == &a2` 的判断出现了不同的结果 ## 总结 个人感觉 c++ 的设计不是很好,首先空类也占用一个字节的空间就是一件让人困惑的事情,所以不得不花很多篇幅去解释这个问题,还要去解决由这个问题引发的空类组合和继承的问题;另外对于空类是不是一定要有不同的地址来去区分不同的对象,这个场景在实际的生产中基本没有碰到过,就算是真的有这样的场景,也可以让用户自己增加成员变量去实现;最重要的,这样的设计会带来**不必要**的内存和性能的开销,而这种开销还**不可避免** ## 链接 - 参考代码: <https://github.com/hpifu/md-tech/tree/master/hatlonely/code/empty-class> - 空类的作用: <https://blog.csdn.net/u014613043/article/details/51323808> - C++ 中的空类与空结构体大小: <https://www.cnblogs.com/kuliuheng/p/4104213.html> > 转载请注明出处 > 本文链接:[https://tech.hatlonely.com/article/58](https://tech.hatlonely.com/article/58)

有疑问加站长微信联系(非本文作者))

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:1006366459

171 次点击  
加入收藏 微博
被以下专栏收入,发现更多相似内容
下一篇:golang 反射
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传