可能重複:
When should I use C++ private inheritance?實踐中使用非公有C++繼承的頻率如何?
我想使這個社區維基,但看不到按鈕...有人可以增加嗎?
我想不出任何我以非公開方式從班級派生出來的任何情況,而且我無法記起這樣做的副代碼。
我希望聽到現實世界中有用的示例和模式。
可能重複:
When should I use C++ private inheritance?實踐中使用非公有C++繼承的頻率如何?
我想使這個社區維基,但看不到按鈕...有人可以增加嗎?
我想不出任何我以非公開方式從班級派生出來的任何情況,而且我無法記起這樣做的副代碼。
我希望聽到現實世界中有用的示例和模式。
您的里程可能會有所不同?
硬核的答案是非公有繼承是無用的。
就個人而言,我用它在以下兩種情況:
來覆蓋virtual
功能在任何一種情況下,我於是用private
繼承因爲繼承本身是一個實現細節。
我已經看到人們更加寬鬆地使用private
繼承,並且在編寫包裝器或擴展行爲時系統地使用,而不是寫作。 C++不提供「簡單」的委託語法,因此可以編寫using Base::method;
以立即提供該方法,而不必編寫正確的轉發呼叫(及其所有重載)。我會認爲這是不好的形式,儘管它確實節省了時間。
如果您選擇繼承來開發包裝,那麼需要繼承私有繼承。您不再需要或不想從包裝類外部訪問基類的方法和成員。
class B;
class A
{
public:
A();
void foo(B b);
};
class BWrap;
class AWrap : private A
{
public:
AWrap();
void foo(BWrap b);
};
//no longer want A::foo to be accessible by mistake here, so make it private
有時繼承其既不具有任何virtual
功能,也不是virtual
析構函數(例如STL容器)的類,則可能必須去非public
繼承。例如
template<typename T>
struct MyVector : private std::vector<T>
{ ... };
這將禁止,手柄底座(vector<>
)的(指針或引用),以獲得衍生class
(MyVector<>
)的保持:
vector<int> *p = new MyVector<int>; // compiler error
...
delete p; // undefined behavior: ~vector() is not 'virtual'!
因爲,我們在第一線本身得到編譯器錯誤,我們將從後續行中的未定義行爲中保存。
但是,爲什麼你會在這裏使用私有繼承而不是組合;)? –
@MatthieuM。雖然這是一個品味問題,但是作文不會允許像'is_base_of <>'這樣的操作。 :) – iammilind
我知道在C++ 11中SFINAE上下文中的訪問規則發生了一些變化......我不認爲'is_base_of'允許'public'訪問使用基類的知識,並且'私人客戶可以隨時查詢成員本身......那有什麼用? –
如果您從沒有虛擬析構函數的類派生,則公共繼承導致該類的用戶可能會調用指向基礎的指針上的delete,從而導致未定義的行爲。
在這種情況下,使用私有繼承是有意義的。
這最常見的例子是從沒有虛擬析構函數的STL容器中私有派生。
C++FAQ具有延伸到許多現實生活的場景私有繼承的一個很好的例子。
一個合法的,長期使用的私有繼承是當你想建立一個Fred類,在一個類威爾瑪使用代碼,並且從類威爾瑪代碼需要從你的新類,弗雷德調用成員函數。在這種情況下,弗雷德在威爾瑪稱非虛擬化,而威爾瑪本身調用(通常是純虛擬),這被弗雷德覆蓋。這對於構圖來說會更難。
代碼示例:
class Wilma {
protected:
void fredCallsWilma()
{
std::cout << "Wilma::fredCallsWilma()\n";
wilmaCallsFred();
}
virtual void wilmaCallsFred() = 0; // A pure virtual function
};
class Fred : private Wilma {
public:
void barney()
{
std::cout << "Fred::barney()\n";
Wilma::fredCallsWilma();
}
protected:
virtual void wilmaCallsFred()
{
std::cout << "Fred::wilmaCallsFred()\n";
}
};
由於private
繼承作爲其唯一已知的使用實施繼承,因爲這總是可以使用遏制,而不是做(這是少用簡單,但更好的封裝的關係),我會說這是使用過經常。
(因爲從來沒有人告訴我什麼protected
繼承意味着,假設沒有人知道它是什麼,假裝它不存在。)
非公有制(幾乎總是私人的)繼承使用(只)行爲,而不是界面。我主要使用它,但不是專門用於mixin中的 。
有關的話題了很好的討論,你可能需要閱讀巴頓和 Nackman(科學與工程C++:用先進的 技巧與實例介紹,ISBN 0-201-53393-6 儘管這本書的大部分內容都是 適用於所有C++,不僅僅是科學和工程 應用程序。儘管它的日期,它仍然值得一讀。)
你不能再提問題了。如果你願意,你可以標記這些mods爲你做。 – sbi
也在類似的領土http://stackoverflow.com/questions/2090661/protected-inheritance。這兩個問題都表明,有些情況下人們使用非公有繼承,相當可辯(不是我說你在攻擊它!)。 – AAT