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

roa*_*alz 5 c++ compiler-warnings visual-c++

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

struct Base {
int a;
}

class Derived:public Base {
private:
int a;
...

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

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

Ray*_*hen 5

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

假设你有一个类库,其中一个类是这样的:

struct Base {
    int a;
};
Run Code Online (Sandbox Code Playgroud)

之后,正在使用您的类库的客户A写道:

class DerivedA : public Base {
private:
    int a;
};
Run Code Online (Sandbox Code Playgroud)

在这种情况下,阴影可能是无意的.客户不小心蒙上阴影Base::a.

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

class DerivedB : public Base {
private:
    int b;
};
Run Code Online (Sandbox Code Playgroud)

到现在为止还挺好.现在你建立你的库,它使用Base的对象,以及谁在使用你的图书馆消费者B建立起来的,它使用两个代码体BaseDerivedB对象.

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

struct Base {
    int a;
    int b; // new member variable
};
Run Code Online (Sandbox Code Playgroud)

这会对您的库造成问题吗?它是否会给客户B带来问题?

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

您使用的所有代码都Base将继续使用Base,并且可以使用该b成员来获取新b功能.即使将DerivedB对象传递给期望a的函数,阴影Base的事实也没有影响.您使用的函数可以说它将访问成员变量.DerivedbBaseBasebBase

同时,使用的所有客户B的代码DerivedB将继续使用DerivedB,并且当该代码说明时b,它DerivedB::b就像以前一样.P,阴影拯救了这一天!

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

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