EffectiveC++-条款34:区分接口继承和实现继承

一. 内容

  1. 仔细思考,public 继承其实可以分成:函数接口(function interfaces)继承和函数实现(function implemention)继承。这意味着 derived class 不仅可以有 base class 函数的声明,还可以有 base class 函数的实现。

  2. 作为 class 的设计者,有时候你会希望 derived class 只继承成员函数的接口,也就是声明;有时候你又会希望 同时继承函数的接口和实现,但又允许覆写(override)它们继承的实现;又有时候你 希望继承函数的接口和实现,但不允许覆写任何东西。

    • 对于 public 继承,成员函数的接口总是会被继承。因为条款32曾说:public 继承是 is-a 的关系,任何可以作用于 base class 的函数也一定可以作用于 derived class。
    • 对于 pure virtual 函数,可以让 derived class 只继承函数的接口。令人意外的是,对于 pure virtual 函数,base class 可以为其提供一份定义,但唯一可以调用它的方式是:显式使用 class 名称指出。
    • 对于 impure virtual 函数,可以让 derived class 同时继承函数的接口和默认实现。但是注意,继承函数的默认行为可能带来潜在的隐患。如果 derived class 需要特定行为而忘记覆写其函数行为,这将带来很多问题。
    • 对于 non-virtual 函数,可以让 derived class 继承函数的接口和强制实现。意味着不希望 derived class 有不同的行为。

    示例

    class Airplane {
    public:
        virtual ~Airplane() = default;
    
        //pure-virtual  子类继承函数接口,强制覆写
        virtual void ToString() const =0;
        //impure-virtual/virtual  子类继承函数接口和默认函数实现,可覆写
        virtual void Fly();
        //non-virtual   子类继承函数接口和默认函数实现,不可覆写
        void DefaultFly();
    };
    
    class ModelA : public Airplane { //public 子类继承函数接口
    public:
        void ToString() const override;
        void Fly() override;
    };
    
  3. 当你声明成员函数时,避免以下两个问题:

    • 将所有函数都声明为 non-virtual。这会使得 derived class 没有余裕空间进行特化工作。non-virtual 函数还会带来析构问题,见条款7。实际上任何 class 如果打算使用多态性质,都会有若干 virtual 函数。如果你关心 virtual 函数的成本,请参考 80-20 法则:一个典型的程序有80%的执行时间花费在20%的代码身上。这个法则十分重要,这意味着平均而言你的函数调用中可以有80%是virtual,而不冲击程序的大体效率。所以当你担心是否有能力负担 virtual 函数的运行成本时,先关注那举足轻重的20%代码身上。
    • 另一个常见错误是将所有函数都声明为 virtual。有时候是正确的,比如 interfaces class。然而这也可能是 class 设计者缺乏坚定立场的表现,某些函数就是不该在 derived class 中被重新实现,你就应该把它声明为 non-virtual

二. 总结

  1. 接口继承和实现继承不同。在 public 继承之下,derived class 总是继承 base class 的接口。
  2. pure virtual 函数只具体指定接口继承。
  3. 简朴的(非纯)impure virtual 函数具体指定接口继承及缺省实现继承。
  4. non-virtual 函数具体指定接口继承以及强制性实现继承。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值