-虚重载- const函数的虚警告



我有这段代码:

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;
};

导致我- wooverloading -virtualGCC编译器的警告。

我理解这个警告,因为在Point2I中的函数声明隐藏虚函数isserializable.但我不确定是否只是缺少constPoint2I可能导致此警告。

你能帮我理解一下是不是const是什么引起了这个警告还是别的什么?来自gcc的警告描述没有特别提到任何内容。

更新:

我找到了另一个类坐标在我的代码库中,它已经覆盖了这个,GCC没有为此抛出警告。唯一的区别是Point2I协调和我没有将声明为虚的constPoint2I. 它看起来只是const隐藏基类声明。

如果是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<T>派生的不同类型,这将不起作用:

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;
};

有两个问题。

第一个是不同类型的参数

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

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

,在这些函数中参数的引用类型为const Point2I&

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

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

相关内容

最新更新