[英]C++: overriding public\private inheritance
如果B
使用public
從A
繼承, B
可以覆蓋其中一個函數並強制將其設為私有?
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
任何組合都會有什么不同嗎?
如果 B 使用 public 從 A 繼承,B 是否可以覆蓋其中一個函數並強制它是私有的? 不
盡管my_func1()
是在priavte
訪問說明符下聲明的,它仍然可以通過指向class A
的指針調用,實際上指向class B
的對象
對my_func1()
的調用在運行時根據指針指向的對象類型進行評估。 在編譯時,編譯器將my_func1()
調用視為對A::my_func1()
調用,並且由於A::my_func1()
是公共的,因此編譯器不會僅報告錯誤。 只有在運行時才會評估實際的函數調用B::my_func1()
。
當然,您不能通過class B
對象直接調用my_func1()
,因為B::my_func1()
是在私有訪問說明符下聲明的,並且您不能從類外部訪問私有聲明的成員。
反過來呢? 如果繼承類型是私有的 - B 可以強制一個特定的函數是公共的嗎?
不
如果您通過基class A
的指針調用my_func1()
,在編譯時它只是被評估為對A::my_func1()
調用,這是Invalid
因為A::my_func1() is declared private in
類 A 中A::my_func1() is declared private in
如果 A 是純抽象的怎么辦? 這有什么不同嗎?
不
基類是抽象類還是多態的都沒有區別。 將適用相同的規則。
受保護的任何組合都會有什么不同嗎?
不
如前 2 個問題中所述,如果您正在調用指向基類的虛函數徹底指針,那么在編譯時編譯器僅檢查基類中該成員函數的訪問,因為編譯器將其視為對基類成員函數的調用。 對函數的實際調用在run time
進行評估,該功能稱為Runtime Polymorphism
或Dynamic polymorphism
,它獨立於作為編譯時構造的訪問說明符。
所以總結一下,
覆蓋基類的成員不影響訪問
如果 A 是純抽象的怎么辦? 這有什么不同嗎?
它的唯一區別如下,即它們如何(或不能)被使用:
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()
起作用了,因為編譯器看到pa
的靜態類型是A*
,它定義了一個公共函數my_func2()
,所以表達式pa->my_func2()
通過了編譯器的測試。 因此它有效。
但是pb->my_func2()
不起作用,因為pb
的靜態類型是B*
,它有一個私有函數my_func2()
,因此代碼甚至無法編譯!
您覆蓋的內容不會影響訪問。 因此,您可以像創建公共繼承函數的私有覆蓋一樣創建私有繼承函數的公共覆蓋。
私有繼承函數的公共覆蓋顯然必須調用真正的函數,它應該是內聯的,所以編譯器會優化它。
==> If B inherits from A using public, can B override one of the functions and force it to be private?
否。 指向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?
沒有區別(除非您必須在B
定義方法)
==> Would protected make any difference in any combination?
沒有區別(相對於基類)
我正在瀏覽其他人發表的帖子,發現與在派生類中的繼承是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
所以,當我們繼承class B
從class A
使用private/protected
符,則意味着在外面的世界,沒有人知道, class B
從繼承class A
,因此是非法的分配pointer/reference
類型的class B
,以類型的指針/引用class A
。 因此,派生類中私有/受保護的重寫虛函數的訪問僅在public
繼承時才有效。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.