J'étudie pour un examen et on me donne ce code :
#include <iostream>
#include <string>
#include <cmath>
using namespace std;
class Expression {
public:
Expression() = default;
Expression(const Expression&) = delete;
Expression& operator=(const Expression&) = delete;
virtual ~Expression() {}
virtual double eval()const = 0;
virtual void print(ostream& out)const = 0;
friend ostream& operator<<(ostream& out, const Expression& e) {
// cout << "@";
e.print(out);
return out;
}
};
class BinaryExpression : public Expression {
Expression* _e1, * _e2;
char _sign;
virtual double eval(double d1, double d2)const = 0;
public:
BinaryExpression(Expression* e1, Expression* e2, char sign) : _e1(e1), _e2(e2), _sign(sign) {}
~BinaryExpression() override { delete _e1; delete _e2; }
virtual double eval()const override {
cout << "BE eval" << endl;
return eval(_e1->eval(), _e2->eval());
}
virtual void print(ostream& out)const override {
out << '(' << *_e1 << _sign << *_e2 << ')';
}
};
class Sum : public BinaryExpression {
virtual double eval(double d1, double d2)const override {
cout << "Sum private eval" << endl;
return d1 + d2;
}
public:
Sum(Expression* e1, Expression* e2) : BinaryExpression(e1, e2, '+') {}
};
class Exponent : public BinaryExpression {
virtual double eval(double d1, double d2)const override {
cout << "E private eval" << endl;
return std::pow(d1, d2);
}
public:
Exponent(Expression* e1, Expression* e2) : BinaryExpression(e1, e2, '^') {}
};
class Number : public Expression {
double _d;
public:
Number(double d) : _d(d) {}
virtual double eval()const override {
cout << "Num eval" << endl;
return _d;
}
virtual void print(ostream& out)const override {
out << _d;
}
};
int main() {
Expression* e = new Sum(
new Exponent(
new Number(2),
new Number(3)),
new Number(-2));
cout << *e << " = " << e->eval() << endl;
delete e;
}
J'ai utilisé le débogueur pour voir quelles lignes sont exécutées, mais je me demande toujours comment le compilateur a su quelle fonction appeler à chaque fois dans la section main()
où nous appelons e->eval()
Sortie :
BE eval
Num eval
BE eval
Num eval
Num eval
E private eval
Sum private eval
((2^3)+-2) = 6
Étant donné que chaque classe a une fonction d'évaluation, certaines en ont même deux et l'utilisation du pointeur d'expression m'a un peu déstabilisé. Que recherche exactement le compilateur lorsqu'il cherche quelle fonction eval()
à exécuter à chaque fois ?