C++之明智审慎地使用private继承(39)---《Effective C++》

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

C++中public继承被视为一种“is-a”关系,private继承并不是“is-a”关系,只是is-implemented-in-terms-of关系,private继承意味着只有实现部分被继承,接口部分被略去。
下面我们来看看private继承的一些特性:

class Person{...};
class Student:private Person{...};
void eat(const Person& p);
void study(const Student& s);

Person p;
Student s;

eat(p);
eat(s);//error,因为private继承不满足“is-a”关系,编译器不会自动将子类对象还原为父类对象

1)因为private继承并不满足“is-a”关系,仅仅满足is-implemented-in-terms-of关系,private继承只是部分继承,编译器不会自动将一个derived class对象转换为一个base class对象。
2)由private base class继承而来的所有成员,在derived class中都会变成private属性,纵使它们在base class中原本是protected或者public属性。

class Timer{
public:
    explicit Timer(int tickFrequency);
    virtual void onTick() const;
    ...
};
class Widget:private Timer{
private:
    virtual void onTick() const;
    ...
};

策略:

由于复合和private继承都满足is-implemented-in-terms-of关系,当我们面对一个“并不存在is-a关系”的两个classes,其中一个需要访问另一个的protected成员,或需要重新定义其一或者多个virtual函数,那么继承一定是必要的,单纯的复合已经无法解决了,可以采用“复合+继承”策略,同时private继承极有可能成为正统设计策略。

如果考虑过“复合+继承”策略之后,不适合我们才选用private继承。

最后让我们看一个private继承的例子,加深对上面部分的理解:

#include <iostream>
#include <string>
using namespace std;
class Base{
public:
    Base(int xx) :x(xx){

    }
    void show(){
        cout << x << endl;
    }
    virtual void guessWhat()const = 0;
    virtual ~Base(){

    }
private:
    int x;
};
class Derived :private Base{
public:
    Derived(int x) :Base(x){

    }
    virtual void guessWhat()const{
        cout << "I'm so grateful for meeting you!!!" << endl;
    }
    void show(){
        cout << "Derived::show" << endl;
        Base::show();
    }
};

int main(){
    Derived d(10);
    d.show();
    d.guessWhat();
    return 0;
}

运行结果:
这里写图片描述
总结:

1)private继承意味着is-implemented-in-terms-of关系,他通常比复合的级别低,但是当derived class需要访问protected base class中的成员,或者需要重新定义继承而来的virtual函数时,这么设计是合理的;
2)和复合不同,private继承可能造成empty base最优化,这对致力于“对象尺寸最小化”的程序库开发者来说,可能非常重要。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值