我认为下面的示例将解释我正在尝试做的事情。我知道除非它们是协变量,否则我无法覆盖eval()函数的返回类型,因此显然我在做错什么。我的问题是:我如何拥有可以以不同方式求值的多态基类和派生类?
ID Name
1 | Sports
--------------
2 | Films
--------------
3 | Politics
--------------
4 | Movies
编辑:已解决
谢谢大家的建议。我想出了一种方法来实现自己的最终目标。最后,我想要一个多态符号表。我使用了您的一些想法来使它起作用。最大的突破是做到了这种“双面”加功能。要添加两个Var,第一个要求另一个将第一个的值加上另一个:
#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;
}
答案 0 :(得分:2)
一个简单的答案是您不能。在C ++中的覆盖必须返回与原始函数相同的类型。
不过,您可以通过一些技巧来获得更复杂的答案。技巧之一是使用类型擦除的返回值,例如,通过std::any
-在https://en.cppreference.com/w/cpp/utility/any
使用std::any
,函数可以返回他们想要的任何值,但是它将被类型擦除-因此调用者必须知道如何处理该返回值...从某种意义上说,这是一个严格的限制该解决方案的适用范围。但是,还有一个地方。
答案 1 :(得分:1)
你不能。
表达式的静态类型不能取决于对象的动态类型。例如:
public ObjectDTO Mapper(Object input)
{
return new ObjectDTO
{
FirstName = input.FirstName,
SecondName = input.SecondName,
Age = input.Age,
School = input.School,
Email = input.Email
}
}
auto f(Node& n) { return n.eval(); }
是什么类型?
您可以使用std::variant
解决问题,但这意味着基类知道子类可以返回的所有类型。这确实是一个设计问题,您应该解决它。