基的私有虚函数由派生的私有虚函数隐藏

Private virtual function of base is hidden by private virtual function of derived

本文关键字:函数 隐藏 派生      更新时间:2023-10-16

以下代码

class A
{
public:
void g(int x)
{
f(x);
}
protected:
virtual void f(int) = 0;
};
class B: public A
{
protected:
virtual void f(float) = 0;
private:
void f(int x) override final
{
f(float(x));
}
};
class C: public B
{
private:
void f(float) override final {}
};
int
main()
{
C c;
c.g(1);
return 0;
}

编译g++ -Woverloaded-virtual产生上述警告:

x.cc:19:7: warning: ‘virtual void B::f(int)’ was hidden [-Woverloaded-virtual]
void f(int x) override final
^
x.cc:28:7: warning:   by ‘virtual void C::f(float)’ [-Woverloaded-virtual]
void f(float) override final {}
^

我不明白这里隐藏了什么。从C范围内,只有一个可能的重载要fB::f(int)因为C内是私有的。

B的范围来看,有两个,但两者都在B内明确命名。

警告告诉你函数C::f(float)隐藏B::f(int),那是因为它确实如此。访问说明符不会影响重载,因此B::f(int)是私有的这一事实并不重要。即使B::f(int)是公开的,也不会考虑过载解决,这就是"隐藏"所指的。

引用GCC手册:

-Woverloaded-virtual(仅限C++和目标C++) 当函数声明隐藏基类中的虚拟函数时发出警告。例如,在:

struct A {
virtual void f();
};
struct B: public A {
void f(int);
};

fA类版本隐藏在B中,代码如下:

B* b;
b->f();

编译失败。

我不明白这里隐藏了什么。从C范围内,只有一种可能的过载需要f,因为B::f(int)Cprivate

在应用访问规则之前进行名称查找和解析。

C对象中查找名称f时,B::f(int)C::f(float)隐藏。这就是编译器警告您的内容。