在C++中,我想不出一个案子,我想继承私有/保护以免受 基类:为什么我们实际上需要C++中的私有或受保护的继承?
class Base;
class Derived1 : private Base;
class Derived2 : protected Base;
是否真的有用吗?
在C++中,我想不出一个案子,我想继承私有/保护以免受 基类:为什么我们实际上需要C++中的私有或受保护的继承?
class Base;
class Derived1 : private Base;
class Derived2 : protected Base;
是否真的有用吗?
当您希望访问某些基类的成员,但没有将它们暴露在类接口中时,它非常有用。私有继承,也可以看作是某种组成:C++ faq-lite给出了下面的例子来说明这个说法
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
};
获得相同的语义,你也可以写汽车类如下:
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
};
但是,这样做的这种方式有几个缺点:
Private在很多情况下都可以使用。其中之一是政策:
Is partial class template specialization the answer to this design problem?。
另一个场合它是有用的,禁止复制和分配:
struct noncopyable {
private:
noncopyable(noncopyable const&);
noncopyable & operator=(noncopyable const&);
};
class my_noncopyable_type : noncopyable {
// ...
};
因为我们不希望用户拥有noncopyable*
类型的指针指向我们的对象,我们私下得出。这不仅包括不可复制的,也包括许多其他类别(政策是最常见的)。
因为拷贝构造函数和赋值操作符都是私有的,所以如果你公开或私下地获取非拷贝,真的没关系。 – Marcin 2008-12-18 14:53:16
由于@litb在他的回答中声明,私下导出会阻止用户使用指针或对不可复制的指针进行引用my_non_copyable_type的实例。 – 2008-12-18 15:26:23
是的,这也可以防止用户通过指向该不可复制的指针进行删除。 – 2008-12-19 12:30:16
公共继承模型IS-A。
非公有继承模型IS-IMPLEMENTED-IN-TERMS-OF。
遏制模型HAS-A,相当于IS-IMPLEMENTED-IN-TERMS-OF。
Sutter on the topic。他解释了何时选择非公有继承来控制实施细节。
例如,当你想重用实现,而不是类的接口并重写它的虚函数。
我已经在某一点或其他地方使用了私有和受保护的继承。
当你希望某些东西具有基类的行为,然后能够覆盖那个功能,但你不希望整个世界知道它并使用它时,私有继承就很有用。您仍然可以通过让函数返回该接口来使用私有派生类的接口。当您可以通过注册自己来监听回调时它也很有用,因为它们可以使用专用接口注册自己。当你从另一个类派生有用的功能基类,但仅希望它的派生类能够使用它
受保护的传承是非常有用的。
我一次实现了这些数据结构类:
大数组的接口会使它看起来像一个数组,但它实际上是一个链接的l ist是固定大小的简单数组。因此,我宣布它是这样的:
template <typename T>
class CBigArray : public IArray, private CLnkList {
// ...
私有继承主要用于错误的原因。人们将它用于IS-IMPLEMENT-IN-TERMS-OF,正如前面的答案中所指出的那样,但根据我的经验,保留副本而不是继承课程总是更加干净。另一个较早的答案是关于CBigArray的答案,它提供了这种反模式的一个完美例子。
我意识到有可能情况下,当已经-一个不因过分热心运用“保护”工作,但它是更好地修复损坏的类,而不是突破一个新的类。
考虑一下:一个圆是一个椭圆,但[Circle不能代替Ellipse](http://stackoverflow.com/questions/7602102/teach-dynamic-polymorphism-with-simple-example/7677015#7677015),公共继承是***不是***是一种关系,虽然我们经常这么称呼它。 – spraff 2012-01-04 11:43:26
圆确实是一个椭圆。不明白你的意思? – 2013-11-28 09:21:17