条款39:明智而审慎地使用private继承——217

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最优化。这对致力于“对象尺寸最小化”的程序开发者而言,可能很重要。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值