是否应该在没有虚拟的情况下使用私有继承?

时间:2012-07-02 20:52:59

标签: c++ inheritance private encapsulation

在C ++中,如果我有一个类Base,它是Derived的私有基类但Base没有虚函数,那么替换继承与封装是否更清晰在班级Encapsulate?我想在这种情况下继承的唯一好处是可以在派生类中直接访问基类,而不是通过memberVariable。一种或另一种做法被认为是更好的,还是更多的个人风格问题?

class Base {
  public:
    void privateWork();
    // No virtual member functions here.
};

class Derived : Base {
  public:
    void doSomething() {
      privateWork();
    }
};

class Encapsulate {
    Base memberVariable;

  public:
    void doSomething() {
      memberVariable.privateWork()
    }
};

2 个答案:

答案 0 :(得分:2)

如果没有virtual函数,则不应在OO中使用继承。请注意,这并不意味着不得使用它,有一些(有限的)情况,您可能需要(ab)将继承用于OO以外的其他目的。

答案 1 :(得分:2)

请记住,继承模型“Liskov替换”:当且仅当您可以将Foo变量传递给期望Bar的每个函数时,Foo才是Bar。私有继承不会对此进行建模。它模拟组合(Foo以条形图实现)。

现在,你应该总是使用第二个版本,因为它更简单并且表达了更好的意图:对于那些不了解它的人来说,它不那么容易混淆。

但是,有时,私有继承很方便:

class FooCollection : std::vector<Foo>
{
public:
    FooCollection(size_t n) : std::vector<Foo>(n) {};

    using std::vector<Foo>::begin;
    using std::vector<Foo>::end;
    using std::vector<Foo>::operator[];
};

这允许您重用vector的一些功能,而无需手动转发begin,end和operator[]的2个版本(const + non const)。

在这种情况下,你根本没有多态:这不是继承,这是伪装的组合;你无法使用FooCollection作为向量。特别是,您不需要虚拟析构函数。