我不小心在基础结构派生的类中用私有成员隐藏了(基础)结构的一些成员变量。
struct Base {
int a;
}class Derived:public Base {
私人:
int a;
...
在我的情况下,这是一个错误,导致一个鬼鬼祟祟的小虫(幸运地在测试时被捕获) 因为我认为影子成员的目的非常少见(如果根本不被认为是不好的做法),我想知道为什么编译器不会提出至少一个警告(好吧,不是错误,因为在法律上允许阴影)?
我使用的编译器是Microsoft Visual C ++ 2015,警告级别4) 我想知道其他编制者(即GCC)是否会针对这种情况提供具体警告?
答案 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构建了一个使用Base
和DerivedB
个对象的代码体。
几周后,您意识到要获得新功能,您需要向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必须做额外的工作来解决冲突。但重要的是阴影没有创建现有代码中的任何新问题。)
在一天结束时,阴影是好还是坏取决于您引入冲突名称的顺序。这不是编译器可以洞察的东西。