2016-12-01 25 views
6

我意外地在基类结构派生的类中隐藏了一个(基)结构的私有成员的一些成员变量。编译器不应该为派生类中的基础结构的成员变量提出警告吗?

struct base {
int a;
}

类派生的:公共基础{
私人:
INT一个;
...

那是在我的情况有误,造成偷偷摸摸的错误(幸好抓住了,而测试)。
因为我认为有目标的成员是非常罕见的(如果根本不被认为是不好的做法),我想知道为什么编译器没有提出至少一个警告(好吧,不是错误,因为在法律上允许阴影)?

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

+0

gcc也没有提供警告,但有趣的是,这种行为应该如何与多态性整体工作 – Starl1ght

+1

我相信,即使没有'private',在你的例子中隐藏一个变量,几乎总是一个错误。我为[clang](https://llvm.org/bugs/show_bug.cgi?id=31222)和[gcc](https://gcc.gnu.org/bugzilla/show_bug.cgi)提交了一项功能请求。 ID = 78632)。 –

+1

@VittorioRomeo在编写Derived时,如果'Base'中不存在'a'不是错误。 –

回答

4

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

假设你有一个类库和类之一是这样的:

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隐藏的事实bBase没有影响。您使用Base的函数可以说是b,它将访问Base成员变量。

同时,所有使用DerivedB将继续使用DerivedB,当该代码表示​​b,它得到DerivedB::b,就像它以前那样客户B的代码。嘿,阴影拯救了一天! (当然,如果顾客B想要开始利用新的b功能,那么顾客B必须做额外的工作来解决冲突,但重要的是影子没有产生任何新问题在现有代码中)。

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

+1

对,这不是编译器已经洞察的东西,但肯定可以是编译器可以轻松警告的人为错误。 如果遮蔽是由派生类的开发者打算并希望的,他们可能会忽略或抑制警告。 在所有这些情况下,我宁可更多的警告而不愿意的行为...... – roalz

+0

@roalz但是,图书馆作者如何在库本身中引入警告抑制?警告来自客户B的代码,图书馆作者无权访问客户B的代码。 –

+0

恕我直言,因为在“客户”代码中引入了影子(想要或不想要),所以可能要由客户来制止警告。或者我错过了什么? – roalz

相关问题