c++ - 如何使用被覆盖函数中的子类引用覆盖纯虚函数
问题描述
所以我在派生类中覆盖纯虚函数时遇到了问题。类的实现和声明如下所示:
class Base{
private:
size_t id;
public:
virtual bool isEqual(const Base& src) const =0;
};
class Derived: public Base{
private:
string str;
public:
virtual bool isEqual(const Derived& src) const override
{
return (this->str == src.str);
}
};
所以当我像这样实现它时,它会遇到编译器错误,比如
member function declared with 'override' does not override a base class member function
您能否告诉我如何才能做到这一点,也许可以解释一下为什么我的版本不起作用。提前致谢!
解决方案
您不能以这种方式更改函数签名 - 阅读有关协变和逆变的详细信息以及为什么 C++ 不允许函数参数同时使用两者(允许协变返回类型)。
另一方面,如果通过对基的引用来引用另一个对象,则根本不会调用覆盖(实际上:重载!)函数:
Derived d1;
Derived d2;
Base& b2 = d2;
d1.isEqual(b2); // how do you imagine the derived version to get called now???
解决方案的关键是dynamic_cast
:
struct Base
{
virtual ~Base() { }
virtual bool operator==(Base const& other) = 0;
};
struct Derived : Base
{
bool operator==(Base const& other) override
{
auto o = dynamic_cast<Derived const*>(&other);
return o && o->str == this->str;
}
};
请注意,我将函数重命名为operator==
; 这在 C++ 中要自然得多。这样,您可以在上面的示例中与以下示例进行比较:
bool isEqual = d1 == b2;
编辑:
老师告诉我们不能重载操作符
好吧,那么只需恢复重命名...实际上,运算符与其他任何函数一样普通函数,只是调用语法不同(实际上:存在替代变体,您也可以始终调用 as d1.operator ==(d2)
)。
推荐阅读
- ios - 如何让拇指适合自定义尺寸开关?
- node.js - 节点:端口 443 需要提升权限错误
- string - 是否可以将一些值嵌入到 Go 中的另一个字符串中?
- java - Android RecyclerView 无法呈现 SurfaceView(已解决)
- git - 修改了多个文件,只推送了几个文件
- google-sheets - 使用 QUERY 时,如何使数据在使用过滤器时一起移动?
- python - 为什么我在发送时会在方法中收到多个值
作为python中的args - node.js - 如何在 Angular 中从 nodejs 获取数据
- python - django.urls.exceptions.NoReverseMatch:未找到带有参数“(”,)“的“displayTagInfo”的反向。尝试了 1 种模式:['(?P
[^/]+)$'] - android - 使用 span 更改 android 文本视图中的特定段落方向