为什么我们实际上需要C ++中的私有或受保护的继承?

在C ++中,我想不出要从A继承private / protected的情况。基类:

class Base;
class Derived1 : private Base;
class Derived2 : protected Base;

真的有用吗?

Gal Goldman asked 2019-10-27T07:25:01Z
7个解决方案
45 votes

当您想访问基类的某些成员,而又不将其暴露在类接口中时,此功能很有用。 私有继承也可以看作是某种组合:C ++常见问题精简版提供了以下示例来说明此语句

class Engine {
 public:
   Engine(int numCylinders);
   void start();                 // Starts this Engine
};

class Car {
  public:
    Car() : e_(8) { }             // Initializes this Car with 8 cylinders
    void start() { e_.start(); }  // Start this Car by starting its Engine
  private:
    Engine e_;                    // Car has-a Engine
};

为了获得相同的语义,您还可以按照以下方式编写car类:

class Car : private Engine {    // Car has-a Engine
 public:
   Car() : Engine(8) { }         // Initializes this Car with 8 cylinders
   using Engine::start;          // Start this Car by starting its Engine
}; 

但是,这种方式有几个缺点:

  • 你的意图不太清楚
  • 可能导致滥用多重继承
  • 因为您可以访问它的受保护成员,所以它破坏了Engine类的封装。
  • 您可以重写Engine虚拟方法,如果您的目标是简单的合成,则不需要使用该方法
Luc Touraille answered 2019-10-27T07:25:59Z
40 votes

在很多情况下,私有可以很有用。 政策只是其中之一:

局部类模板专业化是否可以解决此设计问题?

另一个有用的场合是禁止复制和分配:

struct noncopyable {
    private:
    noncopyable(noncopyable const&);
    noncopyable & operator=(noncopyable const&);
};

class my_noncopyable_type : noncopyable {
    // ...
};

因为我们不希望用户拥有指向我们的对象的类型noncopyable*的指针,所以我们是私下派生的。 这不仅适用于不可复制,而且也适用于许多其他此类(策略是最常见的)。

Johannes Schaub - litb answered 2019-10-27T07:26:47Z
15 votes

公共继承模型IS-A。
非公共继承模型IS-IMPLEMENTED-IN-TERMS-OF。
容纳模型HAS-A,等效于IS-IMPLEMENTED-IN-TERMS-OF。

对这个话题不屑一顾。 他解释了何时选择非公开继承而不是包含来实现细节。

Greg Rogers answered 2019-10-27T07:27:37Z
3 votes

例如,当您想重用实现而不是类的接口并重载其虚函数时。

Nemanja Trifunovic answered 2019-10-27T07:28:02Z
3 votes

私有继承主要用于错误的原因。 如先前的答案所示,人们将其用于IS-IMPLEMENTED-IN-TERMS-OF,但是根据我的经验,保留副本而不是从类继承总是更干净的做法。 另一个较早的答案(关于CBigArray的答案)提供了此反模式的完美示例。

我意识到在某些情况下,has -a可能由于过度使用“ protected”而无法正常工作,但是修复损坏的类比打破新的类要好。

answered 2019-10-27T07:28:33Z
0 votes

我曾在某一点或其他地方同时使用私有和受保护的继承。

当您希望某些东西具有基类的行为,然后能够覆盖该功能,但又不想让整个世界都知道并使用它时,私有继承非常有用。 您仍然可以通过让函数返回该接口来使用私有派生类的接口。 当您可以让事物注册自己以侦听回调时,这也很有用,因为它们可以使用私有接口注册自己。

当您有一个基类可以从另一个类派生有用的功能,但只希望其派生类能够使用它时,受保护的继承特别有用。

Daemin answered 2019-10-27T07:29:14Z
-1 votes

我曾经将这些数据结构实现为类:

  • 链表
  • 通用数组(抽象)
  • 简单数组(继承自通用数组)
  • 大数组(继承自通用数组)

大数组的接口使它看起来像一个数组,但是,它实际上是固定大小的简单数组的链表。 所以我这样声明:

template <typename T>
class CBigArray : public IArray, private CLnkList {
    // ...
pyon answered 2019-10-27T07:30:14Z
translate from https://stackoverflow.com:/questions/374399/why-do-we-actually-need-private-or-protected-inheritance-in-c