在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