当我添加-Wshadow标志时,编译器(gcc 12.1.0)为以下代码生成以下警告:
prog.cc: In member function 'void Derived::myfunc()':
prog.cc:16:13: warning: declaration of 'i' shadows a member of 'Derived' [-Wshadow]
16 | int i = 3;
| ^
prog.cc:8:9: note: shadowed declaration is here
8 | int i{2};
|
class Base
{
private:
int i{2};
};
class Derived : public Base
{
public:
void myfunc(void)
{
int i = 3;
std::cout << i << "\n";
}
};
我想的是:因为我们不能只在myfunc中使用"i"变量(因为这是编译时错误),所以没有必要发出这样的警告。
你知道为什么编译器在这种情况下会给出警告吗?
2条答案
按热度按时间omhiaaxx1#
隐藏与名称查找有关,而与访问规则无关
这是设计使然,尤其是没有考虑访问规则,而是通过影响查找结果来隐藏。
被遮蔽的
i
是经由继承的类成员,并且此外private
在名称查找将找到什么的意义上与它被遮蔽的事实正交。示例
作为一个例子,为什么这可能是有问题的,考虑以下增量,它引入了一个人为的程序中的错误。
在时间
N
编程:在时间
N+1
编程开发人员更改了
status
参数的名称,但忘记更新函数体,由于查找找到了一个隐藏变量,函数体静默地通过编译:vfwfrxfs2#
基类中的i变量存在于已有的派生类中,函数中又定义了一个同名的变量,函数一进入作用域,名称搜索就终止了,这就是基类中的变量不被使用,而是被声明为隐藏它的原因。