虚函数上的 C++ 多态性

标签 c++ function inheritance polymorphism virtual

我试图弄清楚 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";
}

最佳答案

你需要让leftright成为Expr*Expr&,而不是Expr.

与 Java 不同,C++ 中类类型的变量保存实际实例,而不是对实例的引用。

所以当你这样做的时候:

Expr left = term();

您实际上是在调用 Expr 的复制构造函数,它只会生成 Expr 基类的实例。

在 Java 中,这是非常不同的——你只是设置 left 来引用一些现有的对象,而不是创建一个新的对象。

因此需要让 leftright 成为引用或指针——以便在 C++ 中发生与在 Java 中发生的事情相同的事情。

关于虚函数上的 C++ 多态性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10778991/

相关文章:

c++ - 指向集合或 vector 中对象的指针——重要吗?

c++ - 包装右值引用 lambda 时 std::async 和 std::bind 之间的区别

javascript - 错误: Uncaught TypeError: undefined is not a function

c++ - 这两段代码有什么区别吗?

c# - WinForms 相当于 WPF 的 IsHitTestVisible

c++ - 当作为指向结构的指针的成员传递时,将 C 数组清零

C++ 宏参数

r - 如何在 R 中构建一次汇总多个值的表

javascript - 将多个变量传递给 JavaScript 函数?

c++ - 如何在派生类中创建与基类同名的函数