[英]Inheritance: 'A' is an inaccessible base of 'B'
$ cat inheritance.cpp
#include <iostream>
using namespace std;
class A { };
class B : private A { };
int main() {
A* ab = new B;
}
$
$ g++ inheritance.cpp
inheritance.cpp: In function 'int main()':
inheritance.cpp:9: error: 'A' is an inaccessible base of 'B'
$
我只是不明白這個錯誤。
據我了解,正如本教程所確認的那樣, private
繼承應該只改變class B
成員對外界可見的方式。
我認為私有說明符所做的不僅僅是改變class B
成員的可見性。
通過將繼承設為私有,您基本上是在說,即使 B 從 A 繼承(根本)這一事實也是私有的——外部世界無法訪問/可見。
無需對如果允許會發生什么進行冗長的討論,簡單的事實是它是不允許的。 如果您想使用指向基類的指針來引用派生類型的對象,那么您幾乎無法使用公共繼承。
私有繼承不一定是(甚至通常)打算遵循Liskov替換原則。 公有繼承斷言派生對象可以取代基類的一個對象,和正確的語義仍然將導致。 私有繼承並沒有斷言這一點。 私有繼承所隱含的關系的通常描述是“是根據……實現的”。
公共繼承意味着派生類維護基類的所有功能,並可能添加更多功能。 私有繼承通常意味着或多或少相反:派生類使用通用基類來實現具有更受限接口的東西。
僅舉個例子,讓我們暫時假設 C++ 標准庫中的容器是使用繼承而不是模板實現的。 在目前的系統中, std::deque
和std::vector
是容器, std::stack
是容器適配器,提供了更受限的接口。 由於它基於模板,因此您可以使用std::stack
作為std::deque
或std::vector
的適配器。
如果我們想提供本質上相同的繼承,我們可能會使用私有繼承,所以std::stack
將類似於:
class stack : private vector {
// ...
};
在這種情況下,我們絕對不希望用戶能夠像操作vector
一樣操作我們的stack
。 這樣做可能(並且可能會)違反堆棧的期望(例如,用戶可以在中間插入/刪除項目,而不是像預期的那樣純粹的類似堆棧的方式)。 我們基本上使用vector
作為實現堆棧的便捷方式,但是如果(例如)我們更改了stack
獨立的實現(不依賴於基類)或根據std::deque
重新實現它,我們不希望這影響任何客戶端代碼——對於客戶端代碼,這應該只是一個堆棧,而不是一些特殊的向量(或雙端隊列)。
私有繼承應該只改變 B 類成員對外界可見的方式
確實如此。 而如果
A* p = new B;
被允許,那么任何B
的繼承成員都可以從外部世界訪問,只需創建一個A*
。 由於它們是私下繼承的,因此訪問是非法的,上行也是如此。
clang++
給出了一個更容易理解的錯誤信息:
example.cpp:9:13: error: cannot cast 'B' to its private base class 'A'
A* ab = new B;
^
example.cpp:6:11: note: declared private here
class B : private A { };
^~~~~~~~~
1 error generated.
我不是 C++ 專家,但看起來這只是不允許的。 我會去看看規范,看看我想出了什么。
編輯:這是規范中的相關參考 - 第4.10節指針轉換,第 3 段:
“指向cv
D
指針”類型的純右值(其中D
是類類型)可以轉換為“指向 cvB
指針”類型的純右值,其中 B 是D
的基類。 如果B
是D
的不可訪問或不明確的基類,則需要這種轉換的程序是格式錯誤的。
這很簡單: A
被私下繼承的事實意味着B
擴展A
的事實是一個秘密,只有B
“知道”它。 這就是私有繼承的定義。
私有繼承意味着在派生類之外,繼承信息是隱藏的。 這意味着您不能將派生類強制轉換為基類:調用者不知道這種關系。
這是工作
#include <iostream>
using namespace std;
class A{
public:
virtual void update() = 0;
};
class B: public A{
public:
virtual void update(){std::cout<<"hello";};
};
int main()
{
A *a = new B();
a->update();
return 0;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.