簡體   English   中英

C++ 將私有純虛擬方法覆蓋為公共

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM