如何使用不同的签名

时间:2018-02-06 09:12:16

标签: c++ overloading clang++ derived-class

我正在集成来自其他开发人员的代码库。我偶然发现了以下情况:

#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 ......

2 个答案:

答案 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)并确保它的作用是有意义的;即使这意味着如果使用也会抛弃或无法编译。