文章目录
private继承的规则——217
(1)如果class之间的继承关系是private,编译器不会自动将一个派生类的对象转换为一个基类对象
(2)有private 基类继承而来的所有成员,在派生类中都会变成private属性,纵使它们在基类中原本是protected或public属性。
private继承意味implemented-in-terms-of——217
条款34:private继承意味只有实现部分被继承,接口部分应略去。如果D以private形式继承B,意思是D对象根据B对象实现而得,在没有其他意涵了。
何时选择private继承——218
条款38中指出复合的意义也有is-implemented-in-terms-of。
在两者之间取舍时,尽可能使用复合,以下两种情况:
当protected成员和/或virtual函数牵扯进来的时候考虑选择private继承——218
我们来修修改Widget类,这里面调用Timer的一个成员函数:
class Timer{
public:
explicit Timer(int tickFrequency);
virtual void onTick() const; //定时器每滴答一次,此函数就被自动调用一次
};
//我们必须以private形式继承Timer:
class Widget:private Timer{
pviate:
virtual void onTick() const; //查看Widget的数据...等等。
};
这是个好设计,但是我们可以采用以public形式继承Timer并重新定义onTick,然后放一个这种类型的对象与Widget内:
class Widget{
private:
class WidgetTimer:public Timer{
public:
virtual void onTick() const;
...
};
WidgetTimer timer;
...
};
采用public继承加复合两种理由:
(1)你想设计Widget使它得以拥有派生类,但同时你可能会阻止派生类重新定义onTick。
(2)你想要将Widget的编译依存性降至最低。
当继承空类使用private继承——220
我们来定义一个空类:
class Empty{};
class HoldsAnInt{
private:
int x;
Empty e;
};
我们会发现sizeof(HoldsAnInt)>sizeof(int)。但是如果你继承Empty,而不是内含一个那样类型的对象:
class HoldsAnInt:private Empty{
private:
int x;
};
我们又会发现sizeof(HoldsAnInt)==sizeof(int),这就是EBO(empty base optimization:空白基类最优化)。
总结——222
(1)private继承意味is-implemented-in-terms-of。它通常比复合的级别低。但是当派生类需要访问protected 基类的成员,或需要重新定义继承而来的虚拟函数时,这么设计是合理的。
(2)和复合不同,private继承可以造成empty class最优化。这对致力于“对象尺寸最小化”的程序开发者而言,可能很重要。