關於warning: direct base 'A' inaccessible in 'D' due to ambiguity的一些討論

c++ primer習題中發現的問題,習題是18.13。

這個問題很久前有過討論,不過沒有得出正確結論,原貼。

先上代碼:

struct A {
	virtual ~A() {}
};

struct B : A {};

struct C : B {};

struct D : B, A {};

繼承層次很清楚,就是照着書上抄的,沒寫實例化。使用如下編譯命令:
g++ -o test -Wall test.cpp
得到如下警告:
warning: direct base 'A' inaccessible in 'D' due to ambiguity

gdb調試發現D中兩個獨立的A被正確構造。很奇怪一般二義性不會在定義類的時候被警告,想了下,發現原因其實很簡單。

在D中的兩個A的完整訪問應該是D::B::A和D::A,但問題是D::A同樣可以指向D::B::A,因爲這個過程發生的是名字查找,每條路徑都由內而外遵循名字查找規則,而每條路徑都非虛或都虛的情況下,路徑長短不作爲區別優先的根據。所以無論如何第二個A實例都無法被訪問。

之所以會遇到這個問題是因爲我從java轉c++,寫全名寫慣了,囧。

原貼中提到了另一個問題,我想這應該是很多人的第一反應:“是不是編譯器要求虛繼承呢?”繼承層次改爲:

struct A {
	virtual ~A() {}
};

struct B : A {};

struct C : B {};

struct D : B, virtual A {};

或者:
struct A {
	virtual ~A() {}
};

struct B : virtual A {};

struct C : B {};

struct D : B, A {};

可不可以呢?這時候奇葩的事情就發生了,見原貼14樓,這應該是可以的,理由見c++ primer 17.3.6.2的第二款,虛繼承優先級低於派生實例。但是我的g++ 4.7.2在實例化訪問時報error:ambiguity。這個我就沒法解釋了。反正這種繼承層次就是不合理的,避免就好。
發佈了19 篇原創文章 · 獲贊 2 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章