为什么派生类可以从基类中获得相同的数据成员?

时间:2013-08-30 18:38:26

标签: c++ inheritance data-members

由于在基类和派生类中都有相同的数据成员,因此会产生很多混淆,并且需要使用范围解析运算符来解决冲突。那么为什么它在C ++中被允许呢?有人能告诉我这个需要吗?

3 个答案:

答案 0 :(得分:4)

我不知道确切的动机,但我相信这是几个类似案例的简单扩展,这是不可避免的。例如考虑多重继承 - 许多基类可能具有相同的成员,并且作为派生类的创建者,基本上没有什么可以做的。更糟糕的是CRTP - 你不可能知道基类的成员,因为它是任意的。这些案例似乎比你的问题主题更容易混淆,而且问题更多,因为它们不能简单地被禁止而不会削弱某些功能。既然必须解决歧义问题,那么用同样的统一规则处理这个特殊情况似乎很自然。

答案 1 :(得分: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;
}

在这里你可以看到,如果没有黯然失色,使用可变参数模板会更加困难。另外,获得&lt;&gt; std :: tuple中的方法有类似的实现。

答案 2 :(得分:1)

在合理的设计中,这永远不应成为问题。如果您明知创建与您的基地同名的成员,那么您的设计就会出现问题。如果您在不知情的情况下这样做,您将不会注意到。

另一方面,如果在语言级别禁止这样做,那么不知不觉部分就会成为一个难题。考虑使用您继承的框架。现在考虑有公开接口,有很好的文档记录,但任何私有的都没有记录。现在你需要继承一个类型(比如一个Window),你就拥有了一个具有美丽有意义名称的变量,这个名字在世界上都很有意义。您将其添加到您的类型,仅运行编译器以找出该名称已在基本类型中使用(或在层次结构中的某个位置)...