2013-08-30 57 views
2

由於在基類和派生類中都有相同的數據成員,因此會產生很多混淆,並需要使用範圍解析運算符來解決衝突。那麼爲什麼它允許在C++中?任何人都可以告訴我這需要嗎?爲什麼派生類可能具有與基類相同的數據成員?

+5

因爲一般情況下允許遮陰,對班級沒有特別的要求。 –

+1

你的意思是這樣嗎? http://coliru.stacked-crooked.com/view?id=3d6fa652a3 – Chemistpp

回答

4

我不知道確切的動機,但我相信這是幾個類似案例的簡單延伸,它是不可避免的。例如考慮多重繼承 - 許多基類可能具有相同的成員,並且基本上沒有關於它的任何事情可以作爲派生類的創建者。 CRTP更糟糕 - 你不可能知道基類的成員,因爲它是任意的。這些情況看起來不像你的問題那麼容易混淆,而且更麻煩些,因爲在不削弱某些功能的情況下不能簡單地禁止它們。由於無論如何都必須解決模棱兩可的問題,因此用特定的統一規則處理這個特殊情況似乎是很自然的。

+0

還有一些情況下,你明確想要掩蓋,就像在可變模板中一樣。像C++中的許多其他功能一樣,如果使用正確,它可以非常強大。 –

1

在一個明智的設計中,這絕不應該是一個問題。如果你是明知故障創建與你的基地名稱相同的成員,這是你的設計有一個問題。如果你不知不覺做到這一點,你不會注意到。另一方面,如果這在語言層面被禁止,他們不知不覺地部分將成爲一個硬性錯誤。考慮使用您繼承的框架。現在考慮一下有公共接口,這是有據可查的,但任何私人的都是無證的。現在你需要從一個類型繼承(比如說一個Window),並且這個變量帶有一個美麗的有意義的名字,這個名字使得世界上的所有感覺都變得有意義。您可以將其添加到您的類型中,只運行編譯器以發現名稱已用於基本類型(或層次結構中的某處)...

+0

我的印象是,你認爲遮遮掩掩從來不是一個好的做法,這是不正確的。在各種模板中,陰影是許多情況下的最佳實踐:) –

+0

@ViniciusMiranda:如果那是你的印象,我是一個可怕的作家。遮掩是唯一的*選項,這是有道理的。不僅在泛型代碼中,即使在非泛型的純OO代碼中,您可能也需要使用其他代碼,並且您甚至可能不知道其數據成員的名稱(從文檔中,您始終可以閱讀標題)。會出現衝突,並且要求避免可能不知道使用的名稱,或者升級到新版本的庫並且無法編譯,因爲它們使用了需要重構的新名稱,這很奇怪。 –

+0

上一個我給人的印象是你說這是一個不好的習慣,但是不可避免的。我認爲現在很清楚。謝謝:) –

2

遮陰不總是不好。一個陰影非常重要的反例是當我們使用可變參數模板(尤其是元組)時

示例:考慮以下簡化的元組實現。這是我看到如何使用可變模板的第一個例子。

template<typename... T> class tuple0; 

template<> class tuple0<> {}; // end recursion 

template<typename Head, typename... Tail> 
class tuple0<Head, Tail...> : public tuple0<Tail...> { 
public: 
Head head; 
}; 

假設現在我們要建立tuple0<int, double>和訪問這兩個元素。這是一個測試程序,它是

int main() 
{  
    tuple0<int, double>* t1 = new tuple0<int, double>; 
    t1->head = 7; // set the integer value 
    std::cout << "integer: " << t1->head << std::endl; 
    tuple0<double>* t2 = static_cast< tuple0<double>* >(t1); 
    t2->head = std::cos(2); // set the double value 
    std::cout << "double: " << t2->head << std::endl; 
    return 0; 
} 

在這裏你可以看到,如果沒有掩蓋,這將是更難與可變參數模板。另外,std :: tuple中的get方法也有類似的實現。

+0

這就是爲什麼我不同意「在合理的設計中,這不應該成爲問題」的說法。在可變模板中,遮蓋是最佳實踐! :) –

+1

+1此示例顯示我需要課堂數據成員蒙上陰影 – ZijingWu

+0

您錯誤地理解了句子*在一個合理的設計中,這永遠不應該是一個問題*。雖然我會避免讓用戶首先訪問元組內部(通過提供幫助函數,從而打破了我使用的名稱的依賴關係),但這對於get函數是一個明智的設計,並且遮蔽是正確的,因此它不是問題。 –

相關問題