由於在基類和派生類中都有相同的數據成員,因此會產生很多混淆,並需要使用範圍解析運算符來解決衝突。那麼爲什麼它允許在C++中?任何人都可以告訴我這需要嗎?爲什麼派生類可能具有與基類相同的數據成員?
回答
我不知道確切的動機,但我相信這是幾個類似案例的簡單延伸,它是不可避免的。例如考慮多重繼承 - 許多基類可能具有相同的成員,並且基本上沒有關於它的任何事情可以作爲派生類的創建者。 CRTP更糟糕 - 你不可能知道基類的成員,因爲它是任意的。這些情況看起來不像你的問題那麼容易混淆,而且更麻煩些,因爲在不削弱某些功能的情況下不能簡單地禁止它們。由於無論如何都必須解決模棱兩可的問題,因此用特定的統一規則處理這個特殊情況似乎是很自然的。
還有一些情況下,你明確想要掩蓋,就像在可變模板中一樣。像C++中的許多其他功能一樣,如果使用正確,它可以非常強大。 –
在一個明智的設計中,這絕不應該是一個問題。如果你是明知故障創建與你的基地名稱相同的成員,這是你的設計有一個問題。如果你不知不覺做到這一點,你不會注意到。另一方面,如果這在語言層面被禁止,他們不知不覺地部分將成爲一個硬性錯誤。考慮使用您繼承的框架。現在考慮一下有公共接口,這是有據可查的,但任何私人的都是無證的。現在你需要從一個類型繼承(比如說一個Window
),並且這個變量帶有一個美麗的有意義的名字,這個名字使得世界上的所有感覺都變得有意義。您可以將其添加到您的類型中,只運行編譯器以發現名稱已用於基本類型(或層次結構中的某處)...
我的印象是,你認爲遮遮掩掩從來不是一個好的做法,這是不正確的。在各種模板中,陰影是許多情況下的最佳實踐:) –
@ViniciusMiranda:如果那是你的印象,我是一個可怕的作家。遮掩是唯一的*選項,這是有道理的。不僅在泛型代碼中,即使在非泛型的純OO代碼中,您可能也需要使用其他代碼,並且您甚至可能不知道其數據成員的名稱(從文檔中,您始終可以閱讀標題)。會出現衝突,並且要求避免可能不知道使用的名稱,或者升級到新版本的庫並且無法編譯,因爲它們使用了需要重構的新名稱,這很奇怪。 –
上一個我給人的印象是你說這是一個不好的習慣,但是不可避免的。我認爲現在很清楚。謝謝:) –
遮陰不總是不好。一個陰影非常重要的反例是當我們使用可變參數模板(尤其是元組)時
示例:考慮以下簡化的元組實現。這是我看到如何使用可變模板的第一個例子。
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方法也有類似的實現。
這就是爲什麼我不同意「在合理的設計中,這不應該成爲問題」的說法。在可變模板中,遮蓋是最佳實踐! :) –
+1此示例顯示我需要課堂數據成員蒙上陰影 – ZijingWu
您錯誤地理解了句子*在一個合理的設計中,這永遠不應該是一個問題*。雖然我會避免讓用戶首先訪問元組內部(通過提供幫助函數,從而打破了我使用的名稱的依賴關係),但這對於get函數是一個明智的設計,並且遮蔽是正確的,因此它不是問題。 –
- 1. 爲什麼基類的成員與派生類中的同一成員不同?
- 2. 爲什麼派生類繼承基類的私有成員?
- 3. 基數和派生類中的相同數據成員
- 4. C++從派生類訪問私有成員到另一個派生類(兩者具有相同的基類)
- 5. 爲什麼在派生類中找不到基類成員C++
- 6. 爲什麼派生類不能訪問受保護的基類成員?
- 7. 基數與派生類之間的繼承數據成員C++
- 8. 爲什麼我可以通過派生對象的基類指針訪問派生的私有成員函數?
- 9. 派生類可以訪問其基類的私有成員
- 10. 爲什麼我不能將指向派生類成員函數的指針轉換爲相同的Base類?
- 11. 調用與多個派生類基類的成員函數
- 12. C++派生類訪問基類成員
- 13. C++派生類重寫與其他派生類的基類成員?
- 14. 從派生類訪問基類的受保護數據成員
- 15. 派生類和保護基類的成員數據
- 16. 基類模板的成員超出派生類模板中具有相同模板參數的作用域
- 17. 檢查派生類的數據成員
- 18. 爲什麼基類函數沒有被同名的派生類函數隱藏
- 19. 爲什麼靜態數據成員不能與非靜態數據成員具有相同的名稱?
- 20. 爲什麼我的派生類不能傳遞給基類?
- 21. C++聯基類成員派生類成員
- 22. 訪問基類成員中派生
- 23. 派生類不能使用成員指針受保護的基類成員
- 24. 派生類模板沒有看到基類的成員
- 25. 如何在派生類中訪問基類的私有數據成員?
- 26. 基類的私有數據成員如何被派生類訪問?
- 27. 基本模板類數據成員在派生模板類中不可見?
- 28. 爲什麼派生類不能引用基類?
- 29. 爲什麼派生類不能訪問基類靜態方法?
- 30. 爲什麼事件不能在派生類中以與C#中的基類相同的方式使用?
因爲一般情況下允許遮陰,對班級沒有特別的要求。 –
你的意思是這樣嗎? http://coliru.stacked-crooked.com/view?id=3d6fa652a3 – Chemistpp