【问题标题】:-Woverloaded-virtual warning for const function- const 函数的超载虚拟警告
【发布时间】:2021-10-16 14:08:35
【问题描述】:

我有这段代码:

class ISerializable
{
        public:
            virtual bool operator==(const ISerializable* /*value*/) const { return false;};
            virtual bool operator!=(const ISerializable* /*value*/) const { return true;};
};

class Point2I : public ISerializable
{
        public:
            bool operator==(const Point2I& value)
            {
                return (x == value.x && y == value.y);
            }

            bool operator!=(const Point2I& value)
            {
                return !(*this == value);
            }
            public:
            int x;
            int y;
};

class Coordinate : public ISerializable
{
         public:
            virtual bool operator==(const Coordinate& value) const;
            virtual bool operator!=(const Coordinate& value) const;
};

这导致我在 gcc 编译器上出现 -Woverloaded-virtual 警告。

我理解这个警告,因为 Point2I 中的函数声明对 ISerializable 隐藏了虚函数。 但我不确定在 Point2I 中缺少 const 是否会导致此警告。

能否请您帮助我了解导致此警告的原因是 const 还是其他原因?来自 gcc 的警告描述没有具体提及任何内容。

更新:

我在我的代码库中发现了另一个类 Coordinate,它已经覆盖了这个并且 gcc 没有为此抛出警告。 Point2ICoordinate 的唯一区别是我没有在 Point2I 中用 const 声明它虚拟。似乎只是 const 隐藏了基类声明。

【问题讨论】:

  • 总是使用override关键字,它会产生编译错误而不是警告。
  • 关于更新后的问题:您得到的任何答案都没有解释发生了什么吗? const 或没有 const - 您会收到有关重载 virtual 方法而不是覆盖它的警告。我认为这两个答案都解释了这一点,我想我也解释了你实际上如何可以 override virtual 方法。

标签: c++ class operator-overloading declaration gcc-warning


【解决方案1】:

如果是 const 导致此警告或其他原因?

我会说它是别的东西,即您实际上并没有覆盖基类方法,即使您添加了const

参数const ISerializable*const Point2I&不同。


一种解决方案可能是覆盖基类方法,使用const ISerializable& 作为参数,并强制转换为覆盖的方法:

class ISerializable {
public:
    // add virtual destructor if you need to delete objects through
    // base class pointers later:
    virtual ~ISerializable() = default;
    virtual bool operator==(const ISerializable&) const { return false; }
    virtual bool operator!=(const ISerializable&) const { return true; }
};

class Point2I : public ISerializable {
public:
    bool operator==(const ISerializable& value) const override {        
        auto rhs = dynamic_cast<const Point2I*>(&value);
        // rhs will be nullptr if the cast above fails
        return rhs && (x == rhs->x && y == rhs->y);
    }

    bool operator!=(const ISerializable& value) const override {
        return !(*this == value);
    }

private:
    int x = 0;
    int y = 0;
};

示例用法:

#include <iostream>

class Foo : public ISerializable {   // another ISerializable 
public:
};

int main() {
    Point2I a, b;
    std::cout << (a == b) << '\n';  // true  - using Point2I::operator==

    Foo f;
    std::cout << (a == f) << '\n';  // false - using Point2I::operator==
    std::cout << (f == a) << '\n';  // false - using ISerializable::operator==

    // this makes the default implementation in ISerializable utterly confusing:
    std::cout << (f == f) << '\n';  // false - using ISerializable::operator==
}

另一种可能的解决方案是使用CRTP,但如果您想比较从ISerializable&lt;T&gt; 派生的不同类型,这将不起作用:

template<class T>
class ISerializable {
public:
    virtual ~ISerializable() = default;
    virtual bool operator==(const T&) const = 0;
    virtual bool operator!=(const T&) const = 0;
};

class Point2I : public ISerializable<Point2I> {
public:
    bool operator==(const Point2I& value) const override {
        return (x == value.x && y == value.y);
    }

    bool operator!=(const Point2I& value) const override {
        return !(*this == value);
    }

public:
    int x;
    int y;
};

【讨论】:

    【解决方案2】:

    有两个问题。

    第一个是不同类型的参数

    在这些函数中,参数的指针类型为const ISerializable*

    virtual bool operator==(const ISerializable* /*value*/) const { return false;};
    virtual bool operator!=(const ISerializable* /*value*/) const { return true;};
    

    在这些函数中,参数具有引用类型const Point2I&amp;

    bool operator==(const Point2I& value)
    {
        return (x == value.x && y == value.y);
    }
    
    bool operator!=(const Point2I& value)
    {
        return !(*this == value);
    }
    

    第二个是第一个函数是常量成员函数,而第二个函数不是常量成员函数。

    【讨论】:

      猜你喜欢
      • 2017-08-12
      • 2013-09-02
      • 2012-04-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多