2017-08-18 50 views
3

在以下程序中,如果GetPart()被保護而不是私有,那麼這些類中的外部(派生)類或其他成員函數是否會有區別?即是否存在一個編譯錯誤,可能是由於將該函數設置爲私有的而導致的,如果該函數在基類中受到保護,則該編譯錯誤將不存在?重寫一個私有函數,它與protected有什麼不同?

我發現最近可能會覆蓋私人虛擬功能,這讓我很吃驚。在語義上,這對我來說似乎是受保護的工作,而不是私有的。

#include <iostream> 

class A { 
public: 
    A() {} 
    virtual ~A() {} 

    virtual void runFn() { GetPart(); } 

private: 
    virtual void GetPart() = 0; 
}; 

class B : public A { 
public: 
    B() {} 
    virtual ~B() {} 

private: 
    virtual void GetPart() override { std::cout << "GETPART RUN" << std::endl; } 
}; 

int main() 
{ 
    B b; 
    b.runFn(); 
    return 0; 
} 

http://ideone.com/S9681V表明該行確實得到來看,隨着功能得到妥善覆蓋。

+0

覆蓋私人虛擬功能有時是「[功能](https://isocpp.org/wiki/faq/strange-inheritance#private-virtuals)」。 – user1810087

+0

注意:你也可以重載/隱藏私人功能,你不能調用隱藏的功能。 – user1810087

回答

7

本主題引起了很多混淆:即使允許子類覆蓋虛擬私有成員函數,也不允許它們調用它們。

目前,這不會編譯(demo 1):

class B : public A { 
public: 
    B() {} 
    virtual ~B() {} 
private: 
    virtual void GetPart() override { 
     // This line would not compile 
     A::GetPart(); 
     std::cout << "GETPART RUN" << std::endl; 
    } 
}; 

製作GetPart()功能保護將讓上面的代碼編譯沒有問題,但它會要求您提供一個定義(demo 2)。

這是唯一的區別。

+0

只是強調:問題是**只有**訪問說明符**(私有或受保護)。函數是虛擬的事實與它無關 - 你不能從派生類中調用私有成員函數(沒有像派生類成爲基類的朋友那樣的一些變形)。 –

相關問題