由于在基类和派生类中都有相同的数据成员,因此会产生很多混淆,并需要使用范围解析运算符来解决冲突。那么为什么它允许在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