[英]Why can the derived class have the same data members from the base class?
由于在基类和派生类中具有相同的数据成员,因此会产生很多混淆,并且需要使用范围解析运算符来解决冲突。 那么为什么它在C ++中被允许呢? 有人能告诉我这个需要吗?
我不知道确切的动机,但我相信这是几个类似案例的简单扩展,这是不可避免的。 例如考虑多重继承 - 许多基类可能具有相同的成员,并且作为派生类的创建者,基本上没有什么可以做的。 对于CRTP来说更糟-您可能不知道基类的成员,因为它是任意的。 这些案例似乎比你的问题主题更容易混淆,而且问题更多,因为它们不能简单地被禁止而不会削弱某些功能。 由于无论如何都必须解决歧义性问题,因此以相同的统一规则处理该特殊情况似乎是很自然的。
黯然失色并不总是坏事。 阴影非常重要的一个反例是我们使用可变参数模板(尤其是元组)
示例:考虑以下过度简化的元组实现。 这是我看到如何使用可变参数模板的第一个例子。
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 <>方法也有类似的实现。
在合理的设计中,这永远不应成为问题。 如果您故意创建与基础同名的成员,那么您的设计就会出现问题。 如果您在不知不觉中这样做,您将不会注意到。
另一方面,如果在语言级别上禁止这样做,则它们在不知不觉中将成为硬错误。 考虑使用您继承的框架。 现在考虑有公开接口,有很好的文档记录,但任何私有的都没有记录。 现在,您需要从类型(例如Window
)继承,并且此变量具有一个漂亮的有意义的名称,该名称有意义。 将其添加到您的类型中,仅运行编译器以发现该名称已在基本类型(或层次结构中的某个位置)中使用...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.