我试图弄清楚 C++ 中如何处理继承和多态性,它似乎与我在 Java 中习惯的有点不同。我试图在其中一个函数中返回一个基类,但是当收到返回值时,我希望该对象是派生类。然而,它并没有像我预期的那样工作。
#include "Prefixer.h"
using namespace std;
Prefixer::Prefixer( Lexer l ){
lexer = l;
}
Expr Prefixer::expr() {
Expr left = term();
Expr right = termTail();
cout << left.name();
cout << right.name();
return left;
}
Expr Prefixer::term() {
NullExpr temp;
return temp;
}
Expr Prefixer::termTail() {
NullExpr temp;
return temp;
}
但是返回的 left.name() 和 right.name() 都调用了 Expr(基类)的虚拟 name() 函数 :C。我怎样才能使它们从派生类 NullExpr 调用重载的 name() 函数?
string Expr::name() {
return "expr";
}
string NullExpr::name() {
return "null";
}
最佳答案
你需要让left
和right
成为Expr*
或Expr&
,而不是Expr
.
与 Java 不同,C++ 中类类型的变量保存实际实例,而不是对实例的引用。
所以当你这样做的时候:
Expr left = term();
您实际上是在调用 Expr
的复制构造函数,它只会生成 Expr
基类的实例。
在 Java 中,这是非常不同的——你只是设置 left
来引用一些现有的对象,而不是创建一个新的对象。
因此需要让 left
和 right
成为引用或指针——以便在 C++ 中发生与在 Java 中发生的事情相同的事情。
关于虚函数上的 C++ 多态性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10778991/