[英]C++ override private pure virtual method as public
為什么會這樣?
http://coliru.stacked-crooked.com/a/e1376beff0c157a1
class Base{
private:
virtual void do_run() = 0;
public:
void run(){
do_run();
}
};
class A : public Base {
public:
// uplift ??
virtual void do_run() override {}
};
int main()
{
A a;
a.do_run();
}
為什么我可以將PRIVATE虛擬方法覆蓋為公共?
根據https://en.cppreference.com/w/cpp/language/virtual#In_detail覆蓋基類的virtual
成員函數只關心函數名稱、參數、const/volatile-ness 和 ref 限定符。 它不關心返回類型、訪問修飾符或您可能期望它關心的其他事情。
鏈接的參考還特別指出:
Base::vf 不需要可見(可以聲明為私有,或使用私有繼承繼承)被覆蓋。
我找不到任何明確的內容允許這樣做,但覆蓋規則並不能阻止它。 憑借virtual
函數和覆蓋現有的函數而不是不允許這種情況,這是允許的。
如果您要問為什么語言是這樣,您可能需要詢問標准化委員會。
這種行為是有意的。 如果一個方法是虛擬的,那么它意味着可以由派生類自定義,而不管訪問修飾符如何。
看這里
為什么我可以將 PRIVATE 虛擬方法覆蓋為 public ???
因為您以錯誤的角度看待私有的基本方法。 B::do_run
是私有的意味着“只有這個類的成員和朋友才能使用它”。 為了禁止派生類覆蓋它,我們需要單獨的說明符,但我們可以簡單地使它不是virtual
。 另一端的A
類允許任何人調用A::do_run()
,這由A
類設計者決定。 所以沒有你看到的提升。
請注意,此實現不會改變訪問基類和構造的方式:
Base& b = a;
b.do_run();
不管用。
我記得在 Scott Meyers 的“Effective C++”中更詳細地描述了它背后的一些基本原理。 但關鍵的實用特性是能夠在相反的方向使用這種靈活性,在派生類中用私有函數覆蓋公共基類成員,迫使客戶端使用基類作為接口,而不是試圖直接使用派生的應該仍然是一個隱藏的實現。
如果打算為基類編寫私有代碼 & 以防止覆蓋它的可能性,請在基類中實現私有函數,並將其聲明為final
,否則:何時應該使用私有虛擬? ISOCPP.ORG 常見問題
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.