Chinaunix首页 | 论坛 | 博客
  • 博客访问: 5644310
  • 博文数量: 291
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 7924
  • 用 户 组: 普通用户
  • 注册时间: 2016-07-06 14:28
个人简介

阿里巴巴是个快乐的青年

文章分类

全部博文(291)

文章存档

2018年(21)

2017年(4)

2016年(5)

2015年(17)

2014年(68)

2013年(174)

2012年(2)

分类: C/C++

2013-07-03 14:36:13

        假设一个class不带任何数据,即没有non-static成员变量,没有virtual函数(因为这种函数的存在会为每个对象带来一个vptr),也没有vritual base class,换句话说就是所谓的empty class。你猜这种empty class类对象大小是多少呢?一般人会认为其对象应该不占用任何内存,但是事实上你错了
        C++裁定凡是独立(非附属)对象都必须有非零大小,不信请看下面实例:
        class Empty {};
        class HoldsAnInt {
        private:
                int x;
                Empty e;
        };
        测试后你会发现sizeof(HoldsAnInt) > sizeof(int);说明Empty是要求内存的。
        在大多数编译器中sizeof(Empty)为1(g++就是如此),因为面对“大小为0之独立(非附属)对象”,通常C++官方勒令默默安插一个char到空对象内。然而字节对齐可能造成编译器为类似HoldsAnInt这样的class补齐一定的字节,所以HoldsAnInt实际上被放大到足够又存放一个int,在g++中,大小会是8。
        前面一直在强调“独立(非附属)”对象的大小一定不为0,这个约束不适用于derived class对象内的base class成分,因为它们并非独立(非附属)。如果你继承Empty,而不是内含一个那种类型的对象:
        class HoldsAnInt : private Empty {
        private:   
                int x;
        };

        这是sizeof(HoldsAnInt)==sizeof(int)。这就是所谓的EBO(empty base optimization,空白基类最优化)。如果你对空间要求严格,比如:开发公共库、移动端产品,那么EBO,你值得拥有。但是EBO只对单一继承有效,多重继承的话,请另辟蹊径。
        实际上"empty class"并不是真的是empty,虽然其从未拥有non-static成员变量,但是往往内含typedefs、enums、static成员变量,或non-virtual函数。STL就有许多技术用途的empty class,其中内含有用的成员(通常是typedefs),包括base class unary_function和binary_function,这些是“用户自定义之函数对象”通常会继承的class。
        当你面对“并不存在is-a关系”的两个class时,而其中一个需要访问另一个的protected成员,或需要重新定义其一个或多个virtual函数时,private继承极有可能成为正统设计策略。当然一个混合了public继承和复合的设计也能实现这个需求。
        需要注意的是:“明智而审慎地使用private继承”是必要的,只有在考虑完所有方案后,发现其仍然是“表现程序内两个class之间关系”的最佳方案时,才使用它。


        
        
阅读(3650) | 评论(1) | 转发(1) |
给主人留下些什么吧!~~

scq2099yt2013-07-03 14:39:31

文明上网,理性发言...