编译器是否应该对派生类中隐藏的基础结构的成员变量发出警告?

时间:2016-12-01 10:37:02

标签: c++ visual-c++ compiler-warnings

我不小心在基础结构派生的类中用私有成员隐藏了(基础)结构的一些成员变量。

  

struct Base {
  int a;
  }

     

class Derived:public Base {
  私人:
    int a;
  ...

在我的情况下,这是一个错误,导致一个鬼鬼祟祟的小虫(幸运地在测试时被捕获) 因为我认为影子成员的目的非常少见(如果根本不被认为是不好的做法),我想知道为什么编译器不会提出至少一个警告(好吧,不是错误,因为在法律上允许阴影)?

我使用的编译器是Microsoft Visual C ++ 2015,警告级别4) 我想知道其他编制者(即GCC)是否会针对这种情况提供具体警告?

1 个答案:

答案 0 :(得分:5)

阴影是坏还是坏取决于您引入冲突名称的顺序。

假设您有一个类库,其中一个类是:

struct Base {
    int a;
};

稍后,正在使用您的类库的客户A写下:

class DerivedA : public Base {
private:
    int a;
};

在这种情况下,阴影可能是无意的。客户不小心隐藏了Base::a

但是,假设您还有客户B,他写了这个:

class DerivedB : public Base {
private:
    int b;
};

到目前为止一切顺利。现在,您构建了库,因此它使用Base个对象,而使用您的库的客户B构建了一个使用BaseDerivedB个对象的代码体。

几周后,您意识到要获得新功能,您需要向Base添加新成员。

struct Base {
    int a;
    int b; // new member variable
};

这是否会对您的图书馆造成问题?它是否会给客户B造成问题?

不,它不会造成任何问题。

使用Base的所有代码都将继续使用Base,并且可以使用b成员获取新的b功能。即使将DerivedB对象传递给期望Base的函数,Derived遮蔽b的事实也不会影响Base。您使用Base的函数可以说b,它将访问Base成员变量。

与此同时,使用DerivedB的所有客户B的代码将继续使用DerivedB,当该代码显示b时,它会获得DerivedB::b,就像它一样之前。 P,阴影拯救了这一天!

(当然,如果客户B想要开始利用新的b功能,那么客户B必须做额外的工作来解决冲突。但重要的是阴影没有创建现有代码中的任何新问题。)

在一天结束时,阴影是好还是坏取决于您引入冲突名称的顺序。这不是编译器可以洞察的东西。