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

2022-08-29 00:00:00 visual-c++ c++ compiler-warnings

我意外地跟踪了基结构派生的类中具有私有成员的(基)结构的某些成员变量。

结构库{
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构建同时使用BaseDerivedB对象的代码体。

几周后,您意识到为了获得新功能,您需要向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必须做额外的工作来解决冲突。但重要的是,隐藏没有在现有代码中产生任何新的问题。)

在一天结束时,跟踪是好是坏取决于您引入冲突名称的顺序。这不是编译器所能理解的。

相关文章