I'm trying to figure out how inheritance and polymorphism is handled in C++, it seems its a little different than what I'm used to in Java. I'm trying to return a base class in one of the functions, but when the return is received, I would like the object to be the derived class. However it is not working out as expected for me.
#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;
}
But the returned left.name() and right.name() both calls the Expr's (the base class) virtual name() function :C. How can I make it so that they call the overloaded name() functions from the derived class NullExpr?
string Expr::name() {
return "expr";
}
string NullExpr::name() {
return "null";
}
Your problem starts in this code:
Expr Prefixer::term()
{
NullExpr temp;
return temp;
}
temp
is a local variable, destroyed at the end of the function. The return value makes an Expr
instance (because that's the return type) by copying the return expression, temp
. The caller never sees a NullExpr
object.
What Java does is essentially:
Expr* Prefixer::term()
{
NullExpr* temp = new NullExpr;
return temp;
}
but you mustn't blindly do that in C++, or you'll end up with memory leaks (Java has a garbage collector, C++ doesn't). You can free the memory using delete
:
Expr* left = term();
left->name();
delete name;
A more recommended approach is to use smart pointers that automatically destroy the object when the last pointer to it disappears:
shared_ptr<Expr> Prefixer::term()
{
NullExpr* temp = new NullExpr;
return temp;
}