阴影是坏还是坏取决于您引入冲突名称的顺序。
假设你有一个类库和类之一是这样的:
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
将继续使用DerivedB
,当该代码表示b
,它得到DerivedB::b
,就像它以前那样客户B的代码。嘿,阴影拯救了一天! (当然,如果顾客B想要开始利用新的b
功能,那么顾客B必须做额外的工作来解决冲突,但重要的是影子没有产生任何新问题在现有代码中)。
在一天结束时,阴影的好坏取决于引入冲突名称的顺序。这不是编译器已经洞悉的东西。
gcc也没有提供警告,但有趣的是,这种行为应该如何与多态性整体工作 – Starl1ght
我相信,即使没有'private',在你的例子中隐藏一个变量,几乎总是一个错误。我为[clang](https://llvm.org/bugs/show_bug.cgi?id=31222)和[gcc](https://gcc.gnu.org/bugzilla/show_bug.cgi)提交了一项功能请求。 ID = 78632)。 –
@VittorioRomeo在编写Derived时,如果'Base'中不存在'a'不是错误。 –