实现接口时的C++ "overload virtual warning"

C++ "overload virtual warning" when implementing interface

本文关键字:overload warning virtual C++ 接口 实现      更新时间:2023-10-16

下面是我的示例代码:

class Interface {
    public:
        virtual void foo(const Interface &interface) = 0;
};
class A : public Interface {
    public:
        void foo(const A &a) {
                // do something with another object of same type
        }
};
class B : public Interface {
    public:
        void foo(const B &b) {
        }
};

有一个警告:

warning: 'A::foo' hides overloaded virtual function
      [-Woverloaded-virtual]
            void foo(const A &a) {
                 ^
note: hidden overloaded virtual function 'Interface::foo'
      declared here: type mismatch at 1st parameter ('const Interface &' vs
      'const A &')
            virtual void foo(const Interface &interface) = 0;

如何处理这个问题?在派生类中添加using Interface::foo;是最佳解决方案吗?我认为这是一个普遍的问题。非常感谢!

void foo(const A &a)不覆盖void foo(const Interface &interface)。虽然语言允许协变返回类型,但据我所知,你不能有协变参数。

所以你的void foo(const A &a)隐藏(或最多重载)函数的基本版本。

如果你使用c++ 11的override关键字,编译器应该更清楚地告诉你你没有重写。或者,如果你尝试实例化一个A,那么它应该失败,因为A是抽象的,因为它实际上没有覆盖foo

解决方案当然是使派生版本使用与foo完全相同的参数类型。

virtual void foo()函数的virtual部分表明它可以在继承Interface的类中被覆盖。在class AB中,您使用了相同的函数,但更改了参数,这意味着该函数将被重载。

如果你只想在子类中重写函数,使用void foo(const Interface &interface)

在子类中重载虚函数

感谢评论中的@GargAnkit,这是我的总体解决方案:

#include <iostream>
#include <string>
using std::cout;
using std::endl;
class Interface {
    public:
        int compare(const Interface &that) const {
            if (this->to_string() < that.to_string()) {
                return -1;
            } else if (this->to_string() == that.to_string()) {
                return 0;
            } else {
                return 1;
            }
        }
        virtual std::string to_string() const = 0;
};
class A : public Interface {
    public:
        std::string to_string() const override {
            return "A";
        }
};
class B : public Interface {
    public:
        std::string to_string() const override {
            return "B";
        }
};
int main() {
    A a;
    B b;
    cout << a.compare(b) << endl;
    cout << "ok" << endl;
    return 0;
}

要选择一个函数作为基类中函数的覆盖,两个函数必须完全匹配——相同的名称,相同的参数,相同的const/volatile限定。如果函数只在限定条件上不同,它们将被视为完全不相关的函数,并且基函数将不被考虑覆盖。

的例子:* *

class A
{
public:
virtual void fun(..)const{}
};
class B:public A
{
public:
void fun(..){} //violation
};
* *