2011-04-22 154 views
15

如果B繼承自A使用publicB可以覆蓋其中一個函數並強制它是私有的嗎?C++:覆蓋public/private繼承

class A 
{ 
public: 
    virtual double my_func1(int i); 
    virtual double my_func2(int i); 
} 

class B : public A // Notice the public inheritance 
{ 
public: 
    virtual double my_func1(int i); 
private: 
    virtual double my_func2(int i); 
} 

另一種方式呢?如果繼承類型是私有的 - B可以強制某個特定的函數公開嗎?

如果A是純粹的抽象呢?這有什麼不同嗎?

protected會在任何組合中有所不同嗎?

回答

14

如果B使用public繼承A,那麼B是否可以重寫其中一個函數並強制它是私有的? NO

Eventhough的my_func1()priavte訪問指示符聲明它可以通過一個指向class A被稱爲靜止,實際上指向到my_func1()呼叫在被評估的class B

一個對象運行時間取決於指針指向的對象的類型。在編譯時,編譯將my_func1()調用看作A::my_func1()的調用,並且因爲A::my_func1()是公共的,編譯器不會報告唯一的錯誤。僅在運行時纔會對實際函數調用B::my_func1()進行評估。

Ofcourse,你不能直接調用my_func1()通過class B對象,但因爲B::my_func1()下私接符聲明,你不能從類外部訪問聲明爲私有成員。

另一種方式呢?如果繼承類型是私有的 - B是否可以強制某個特定的函數公開?
NO

如果您呼叫my_func1()通過基礎class A的指針,在編譯它只是評估爲呼叫A::my_func1()時間是Invalid因爲A::my_func1() is declared private in類A`

如果A是純抽象的呢?這有什麼不同嗎?
NO
這沒有什麼區別,如果基類是抽象或只是多態性。相同的規則將適用。

受保護會在任何組合中產生任何影響嗎?
NO
作爲第一2 Q的解釋,如果你調用虛函數徹底指針的基類,然後在編譯的時候,因爲編譯器看到它的編譯器僅檢查成員函數的基類的訪問作爲基類成員函數的調用。對函數的實際調用在run time處進行評估,該功能稱爲Runtime PolymorphismDynamic polymorphism,它獨立於Access說明符,它是編譯時構造。

所以在最後,

覆蓋基類的成員,不影響存取

+3

雖然我選擇這個作爲答案,但我建議閱讀其他答案以獲取更多細節 – Jonathan 2011-05-01 22:02:21

+0

因此,私人繼承是危險的嗎?因爲您認爲所有內容都無法訪問,但您可以通過基類訪問私有虛擬方法。 – 2014-08-01 11:00:48

+0

@蘇哈諾夫:不,這並不危險,因爲派生階級完全控制是否可以訪問其私有基類。所以「A * a = new B();」當A是B的私有基類時,不允許使用。 – 2016-02-11 17:36:27

1

您重寫的內容不會影響訪問。因此,您可以創建私有繼承函數的公共覆蓋,就像您創建公共繼承函數的私有覆蓋一樣。

私有繼承函數的公共覆蓋顯然必須調用真正的函數,它應該是內聯的,所以編譯器會優化它。

6

差異

如果一個是純粹的抽象?這有什麼不同嗎?

它使唯一的區別是以下內容,即它們如何能夠(或不能)使用:

A *pa = new B(); 
pa->my_func2(10); //calls B::my_func2() even though its private! 

B *pb = new B(); 
pb->my_func2(10); //compilation error - trying to access private function 

說明

接入符是編譯時構建體,等等,編譯器根據對象(或指針)的類型靜態在編譯時(顯然)檢測到任何違反訪問規則的情況。運行時無法檢測到這種違規行爲。

所以pa->my_func2()作品,因爲編譯器看到的是靜態類型的paA*它已經定義了公共職能my_func2(),所以表達pa->my_func2()通過編譯器的測試。因此它起作用。

pb->my_func2()不起作用,因爲靜態類型的pbB*具有私有函數my_func2(),因此代碼甚至不會編譯!

+0

請告訴我們,如果這是一個糟糕的或不壞的'實行這種結構的做法? – mr5 2013-12-17 23:15:54

+0

@ mr5即便如此,它也是一個潛在問題的流動源。順便說一句,納瓦茲thx非常明確的解釋。 – StahlRat 2014-10-16 15:48:56

1

==> If B inherits from A using public, can B override one of the functions and force it to be private?

NO。指針/參考A將始終將公開爲my_func2。您仍然可以使用A*A&來調用此方法。 (你問的是Java中可能的)。

==> if the inheritance type is private - can B force a specific function to be public?

在第一名,如果繼承類型爲私營/保護,那麼你不能分配派生類對象的基類指針/引用。例如你不能做以下!

A* p = new B; // error 

==> What if A is pure abstract? does it make a difference?

NO差(除非你有B定義的方法)

==> Would protected make any difference in any combination?

NO差(相對於基類)

0

我正在閱讀其他人發佈的帖子,並發現Derived類中的繼承爲private/protected時遇到的錯誤的解釋有點令人困惑/不完整。

考慮下面的代碼片段,

class A 
{ 
public: 
    virtual double my_func1(int i); 
    virtual double my_func2(int i); 
} 

class B : private A // Notice private inheritance 
{ 
public: 
    virtual double my_func1(int i); 
private: 
    virtual double my_func2(int i); 
} 

A* ptr = new B; // this is not legal because B has a private base 
ptr->my_func1(); // my_func1() is not accessible 
ptr->my_func2(); // my_func2() is also not accessible not because it is private but due 
       // base class A being inherited privately 

所以,當我們使用private/protectedclass A繼承class B那麼就意味着,沒有人在外面的世界知道,class Bclass A繼承因此是非法的分配class B類型的pointer/reference指向類型class A的指針/引用。因此,只有在public中繼承時,才能在派生類中訪問private/protected重寫的虛函數。