简体   繁体   English

如何从指向父类的指针调用虚函数

[英]How to call a virtual function from a pointer to a parent class

I am trying to call a virtual function from a pointer to a class from within another class.我试图从另一个类中的一个类的指针调用一个虚函数。 No matter what I do it just calls the original function.无论我做什么,它都只是调用原始函数。 I think I am missing something simple.我想我错过了一些简单的东西。 Here are is the smallest bit of code that reproduces the problem.这是重现问题的最小代码。 Binary and LiteralExpression inherit from Expr. Binary 和 LiteralExpression 继承自 Expr。 They each implement their own accept method.他们每个人都实现了自己的接受方法。

template <typename T>
class LiteralExpression;

template <typename T>
class Unary;

template<typename T>
class Visitor {
public:
    virtual T visitLiteralExpressionExpr(LiteralExpression<T> expr) { T temp;  return temp; };
    virtual T visitUnaryExpr(Unary<T> expr) { T temp;  return temp; };
};

template<typename T>
class Expr {
public:
    virtual T accept(Visitor<T>* visitor) { std::cout << "base accept" << std::endl;  T temp; return temp; };
};

template<typename T>
class Unary : public Expr<T> {
public:
    Unary(Token oper, Expr<T> right) : oper(oper), right(&right) { }

    T accept(Visitor<T>* visitor) {
        std::cout << "unary accept" << std::endl;
        return visitor->visitUnaryExpr(*this);
    }

    Token oper;
    Expr<T> *right;
};

template<typename T>
class LiteralExpression : public Expr<T> {
public:
    LiteralExpression(Literal lit, TokenType type) : lit(lit), type(type) { }

    T accept(Visitor<T>* visitor) {
        std::cout << "literal accept" << std::endl;
        return visitor->visitLiteralExpressionExpr(*this);
    }

    Literal lit;
    TokenType type;
};

Here I test if the right accept methods are being called.在这里我测试是否正在调用正确的接受方法。 I build a Unary expression object with a negative sign and a LiteralExpression object as it's right "leaf".我构建了一个带有负号的一元表达式对象和一个 LiteralExpression 对象,因为它是正确的“叶子”。 If I call the unary expression's accept everything works fine, and if I call the LiteralExpression's accept method directly it works fine as well.如果我调用一元表达式的 accept 一切正常,如果我直接调用 LiteralExpression 的 accept 方法,它也可以正常工作。 But if I try to call the LiteralExpression's accept method through a pointer to it as an Expr object it calls the base accept method instead.但是,如果我尝试通过作为 Expr 对象指向它的指针调用 LiteralExpression 的 accept 方法,它会调用基本的 accept 方法。

void AstPrinter::test()
{
    LiteralExpression<std::string> lit(Literal(123), INTEGER);
    Unary<std::string> unary(Token(MINUS, "-", Literal(true), 1), lit); // -123

    lit.accept(this);          // prints "literal accept"
    unary.accept(this);        // prints "unary accept"
    unary.right->accept(this); // prints "base accept"
}

Any help would be appreciated!任何帮助,将不胜感激! (ignore the unencapsulated/non-const instance data, that's just for debugging stuff) (忽略未封装/非常量实例数据,仅用于调试)

Unary(Token oper, Expr<T> right) : oper(oper), right(&right) { }

This initializes the field right to point to the constructor argument right .这将初始化字段right以指向构造函数参数right When the constructor exits, the arguments are destroyed and the field right becomes a dangling pointer.当构造函数退出时,参数被销毁,字段right变成一个悬空指针。

The type of the argument should be Expr<T>& or Expr<T>* .参数的类型应该是Expr<T>&Expr<T>*

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM