private 继承(effective C++ 条款40)
来源:互联网 发布:青山大禹软件 编辑:程序博客网 时间:2024/05/29 02:15
什么是private继承
我们知道,class的默认访问权限是private的,这一点同样适用于继承,如果忘记加访问权限修饰,class的默认继承方式就是private。但private继承并非要表达继承关系,而是表达 ”根据某物实现出“的概念,这一概念跟我们通常所说的组合方式(has-a)类似,也就是说,private继承关系通常也是表达了组合关系,而非继承。
private 继承的特点
继承的所有成员的访问权限都变为private。这一点的保证主要来自于private的继承权限修饰,由此,无论base class的成员由何种方式修饰,最终都将得到private限定。即使发生重写(virtual函数的重写),任何重新设定的访问限定都是无效的(例如,限定原private virtual 函数重写后的访问权限为public,事实上不会有任何作用,反而误导类的使用者)。
private 不表示 “is a”的关系,因此不会发生隐式类型转换。具体有如下的例子:
class A {};class B:private A {};void func(A& a){}int main() { A a; B b; func(a); // OK func(b); // 错误,不是is a,因此 B不是A,调用失败}
private继承的上述特性还是需要注意的。
在何时使用private继承
首先,必须明确的一点是,private继承的优先级低于组合,尽量使用组合,但private继承也有一些表现优秀的使用场景:
- 需要重写base class的virtual函数或使用其protect成员:
这种情况下,事实上也可以用组合代替,在private限定下,重新定义一个class继承自base class,也可实现这种需求,但这里不做讨论,只需要知道实现这种需求的方法不止一种即可。在private 继承的情况下,我们就可以重写private版本的virtual函数,从而实现对base class 中该功能的重新定义(具体例子请看条款40)。这里要注意的一点是:C++允许对private的虚函数重写(条款35提到这是模板方法设计模式的一种特例),因此,在本书中提到,这也许是private继承的缺陷,按照当时C++ 03的版本,确实无法阻止子类对该private 虚函数的重写,但是 C++ 11 的final关键字可以阻止重写,这一缺陷就不复存在了,具体来讲,一个这样的写法可以避免private virtual 被重写:
class A {public:virtual void vfunc();};class B: private A {private: virtual void vfunc() final; // C++ 11};
2 . EBO(空白基类最优化) (重要)
编译器的EBO也是一个重要的点,这个点可以帮我们引申出一个小的考点,那就是一个独立的empty的class的size到底是多少,我们知道,这个大小通常为1,因为C++规定独立对象都必须有非零大小,因此编译器会安插一个char到该类中,所以size的结果为1.我们必须明确的一点,我们认为只要不包含non-static成员的类都可视作empty class,包括那些包含typedef以及static成员的类。
EBO是指,在发生单一继承关系时,empty class所占的空间1会被忽略。对于多继承,并不适用,此外,并不限定在private继承。
class A{};class B:private A{int x;};sizeof(A) = 1, sizeof(B) = 4; // 继承发生EBO
EBO被广泛使用在STL库中。
总结
- private继承相对组合具有较低使用优先级。
- private继承不具备is a的关系,因此隐式类型转换不存在。
- 在需要重写virtual函数时使用private继承。
- 在EBO中使用private继承。
- private 继承(effective C++ 条款40)
- Effective C++:条款39:明智而审慎地使用private继承
- 读书笔记《Effective C++》条款39:明智而审慎地使用private继承
- Effective C++(条款39-40)
- Effective C++:条款22:将成员变量声明为private
- [effective c++]条款34-区分接口继承和实现继承
- Effective C++:条款34:区分接口继承和实现继承
- 《Effective C++》:条款34:区分接口继承和实现继承
- Effective C++:条款40:明智而审慎地使用多重继承
- 《Effective C++》:条款40:明智而审慎的使用多重继承
- 读书笔记《Effective C++》条款40:明智而审慎地使用多重继承
- C++之明智审慎地使用private继承(39)---《Effective C++》
- Effective C++(条款1-4)
- Effective C++(条款5-12)
- Effective C++(条款13-17)
- Effective C++(条款18-25)
- Effective C++(条款26-31)
- Effective C++(条款32-34)
- Win32——edit控件的简单使用
- 128. Longest Consecutive Sequence
- java基础_设计模式_单例模式
- zookeeper for linux下载安装
- java面试题目01
- private 继承(effective C++ 条款40)
- 数据结构 第八章 排序
- 2017 ACM-ICPC 亚洲区(南宁赛区)网络赛
- 最近的计划
- 阿里云服务器配置(二)
- 深度优先搜索DFS
- java可重入锁(ReentrantLock)的实现原理
- Spring MVC--16.参数接受map
- 配置wordpress时出现403 Forbidden nginx/1.10.2