我正在集成来自其他开发人员的代码库。我偶然发现了以下情况:
#include <iostream>
struct A
{
virtual void test(int a)
{
std::cout << "A::test(" << a << ')' << std::endl;
}
};
struct B : public A
{
// using A::test;
void test(int a, int b)
{
std::cout << "B::test(" << a << ", " << b << ')' << std::endl;
A::test(a);
}
};
int main()
{
B b;
b.test(1, 2);
}
编译此代码不会向g++ -Wall
发出警告,但是clang++ -Wall
我会收到警告:
x.cpp:15:11: warning: 'B::test' hides overloaded virtual function [-Woverloaded-virtual]
void test(int a, int b)
^
x.cpp:5:19: note: hidden overloaded virtual function 'A::test' declared here: different number of parameters (1 vs 2)
virtual void test(int a)
^
1 warning generated.
两种情况下的输出都是:
B::test(1, 2)
A::test(1)
如何解决这种情况?对我来说没有明确的路径,因为目前还不清楚原始程序员的目的是什么。
A::test
实例中隐藏B
的版本,只使用带有附加参数的版本(我认为就是这种情况)。using A::test
语句来消除警告,但调用b.test(1)
将直接调用A::test
,忽略重载。最有可能原作者也不想在A::test
类中公开B
。另一个想法是添加缺失的重载并使其引发异常,例如(在B
中):
void test(int a)
{
throw std::logic_error("unsupported function overload");
}
但这感觉不好,因为它是运行时的东西,我认为编译时应该有错误或警告。
是否有规范的方法来重载A::test
并以不需要-Wno-overloaded-virtual
的方式摆脱警告?
当前解决方案:
class B: public A
{
private:
using A::test;
public:
...
};
这可以消除警告,并在调用b.test(1)
时出错。它仍然可以在它上面调用A::test
......
答案 0 :(得分:2)
可能的解决方案或解决方法可能是将A::test
拉入B
的范围,例如
struct B : A
{
using A::test;
...
};
然后您可以使用普通test(a)
,并且应该调用A::test
。
答案 1 :(得分:1)
虽然你可以在B中使test(int)私有,这将删除警告;你会最终得到一个人可以轻易地将它作为一个&#34; A&#34;对象然后在它上面调用test(int)。我不担心原始工程师的意图,因为他们正在努力调用test(int)并确保它的作用是有意义的;即使这意味着如果使用也会抛弃或无法编译。