编译器是否应该对在派生类中隐藏的基结构的成员变量发出警告?
我意外地跟踪了基结构派生的类中具有私有成员的(基)结构的某些成员变量。
结构库{
派生的类:公共基础{
Int a;
)
私有:
Int a;
...
在我的情况下,这是一个错误,导致了一个偷偷摸摸的错误(幸运的是在测试时被发现)。
由于我认为故意跟踪成员是非常罕见的(如果根本不被认为是糟糕的做法),我想知道为什么编译器没有发出至少一个警告(好的,不是错误,因为跟踪是法律允许的)。
我使用的编译器是Microsoft Visual C++2015,警告级别4)。
我想知道其他编译器(即GCC)是否对这种情况提供了具体的警告?
解决方案
隐藏是好是坏取决于您引入冲突名称的顺序。
假设您有一个类库,其中一个类如下:
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
成员变量。
同时,客户B的所有使用DerivedB
的代码将继续使用DerivedB
,当代码指定b
时,它将得到DerivedB::b
,就像以前一样。哟,影子拯救了世界!
(当然,如果客户B想要开始利用新的b
功能,则客户B必须做额外的工作来解决冲突。但重要的是,隐藏没有在现有代码中产生任何新的问题。)
在一天结束时,跟踪是好是坏取决于您引入冲突名称的顺序。这不是编译器所能理解的。
相关文章