c++ - C++ 派生类重写返回类型
问题描述
我认为我下面的示例将解释我正在尝试做的事情。我知道我不能覆盖 eval() 函数的返回类型,除非它们是协变的,所以很明显我做错了什么。我的问题:我如何拥有可以以不同方式评估自己的多态基类和派生类?
#include <iostream>
class Node {
public:
virtual void eval() = 0;
};
class IntNode: public Node {
public:
IntNode() { val = 0; }
IntNode(int i) { val = i; }
int eval() { return val; }
private:
int val;
};
class FloatNode: public Node {
public:
FloatNode() { val = 0; }
FloatNode(float i) { val = i; }
float eval() { return val; }
private:
float val;
};
int main() {
Node *a = new IntNode(5);
Node *b = new FloatNode(2.3);
std::cout << a->eval() << std::endl;
std::cout << b->eval() << std::endl;
return 0;
}
编辑:已解决
谢谢大家的建议。我已经找到了实现我最终目标的方法。最后我想要一个多态符号表。我使用了你的一些想法来实现这一点。最大的突破就是做了这个“双面”的加号功能。要添加两个 Var,第一个要求另一个将另一个与第一个的值相加:
#include <iostream>
#include <unordered_map>
#include <string>
using namespace std;
class Var {
public:
virtual void print() = 0;
virtual Var *plus(int i) = 0;
virtual Var *plus(float f) = 0;
virtual Var *plus(Var *other) = 0;
};
class IntVar: public Var {
public:
// constructors
IntVar();
IntVar(int i);
void print();
// operations
Var *plus(int i);
Var *plus(float f);
Var *plus(Var *other);
private:
int val;
};
class FloatVar: public Var {
public:
// constructors
FloatVar();
FloatVar(float f);
void print();
// operations
Var *plus(int i);
Var *plus(float f);
Var *plus(Var *other);
private:
float val;
};
// constructors
IntVar::IntVar() { val = 0; }
IntVar::IntVar(int i) { val = i; }
void IntVar::print() { cout << "" << val << endl; }
// operations
Var *IntVar::plus(int i) { return new IntVar(i+val); }
Var *IntVar::plus(float f) { return new FloatVar(f+val); }
Var *IntVar::plus(Var *other) { return other->plus(val); }
// constructors
FloatVar::FloatVar() { val = 0; }
FloatVar::FloatVar(float f) { val = f; }
void FloatVar::print() { cout << "" << val << endl; }
// operations
Var *FloatVar::plus(int i) { return new FloatVar(i+val); }
Var *FloatVar::plus(float f) { return new FloatVar(f+val); }
Var *FloatVar::plus(Var *other) { return other->plus(val); }
int main() {
unordered_map<string, Var *> symbol_table;
symbol_table["a"] = new IntVar(5);
symbol_table["b"] = new FloatVar(2.3);
symbol_table["c"] = symbol_table["a"]->plus(symbol_table["b"]);
symbol_table["a"]->print();
symbol_table["b"]->print();
symbol_table["c"]->print();
return 0;
}
解决方案
一个简单的答案是你不能。C++ 中的重写必须返回与原始函数相同的类型。
然而,一个更复杂的答案是你可以,有一些技巧。其中一个技巧是使用类型擦除的返回值,例如,通过- 在https://en.cppreference.com/w/cpp/utility/anystd::any
上查看更多关于它的用法
使用std::any
,函数可以返回他们想要的任何值,但它会被类型擦除 - 所以调用者必须知道如何处理这个返回值......从某种意义上说,这严重限制了这个解决方案的适用范围。但是,这也有一个地方。
推荐阅读
- service - 在 CHDIR 生成 /opt/Informer5/informer5.sh 步骤失败:没有这样的文件或目录
- pentaho - Pentaho Kettle - 动态获取文件名
- javascript - Ext js 5.0.1 列自定义排序
- python - 从 java 客户端订阅到 python opcua 服务器不起作用
- vue.js - Vuejs的v-for中如何处理组件发出的事件
- sql - 拆分字段并添加小数点以创建数值 SQL
- redis - redis pub sub 仅适用于某组键?
- protractor - 如何使用量角器执行 .exe 文件?
- ruby-on-rails - 编组数据库对象是否安全?
- vba - 无法通过 vba 打开 Microsoft Office 文档映像