I'm trying to define a Tree Node for an expression tree. I want to define an expression tree operator as class Op {}; Ideally this would be in abstract interface, but if it is, then my class TreeNode { private: Op op;} won't work. The only solution I can find is to create a Null base class. There has to be a better approach. I want to utilize inheritance because if I create new operator types (e.g. unary, binary, ternary, subtraction, division, user defiend) I can just create more and more derived classes to class Op without having to modify any of the base behavior of the other objects. Open/Close Principle.
Below is my current solution.
#include <bits/stdc++.h>
using namespace std;
class Op {
public:
virtual bool is_operand() const {return true;}
virtual bool is_operator() const {return false;}
virtual string get_name() const {return string("fake abstract class");}
virtual ~Op(){}
};
class Add : public Op {
public:
bool is_operand() const override {
return false;
}
bool is_operator() const override {
return true;
}
string get_name() const override{
string name("add");
return name;
}
};
class IntOperand : public Op {
private:
int m_value;
public:
IntOperand() : m_value(0) {}
IntOperand(int val) : m_value(val) {}
bool is_operand() const override {
return true;
}
bool is_operator() const override {
return false;
}
string get_name() const override{
string res = to_string(m_value);
return res;
}
};
class VarOperand : public Op {
private:
string m_value;
public:
VarOperand() : m_value("") {}
VarOperand(const string& str) : m_value(str) {}
bool is_operand() const override {
return true;
}
bool is_operator() const override {
return false;
}
string get_name() const override{
return m_value;
}
};
class TreeNode {
public:
Op m_op;
TreeNode * m_left; //probably should be private.
TreeNode * m_right;
TreeNode(const Op& op) : m_op(op), m_left(nullptr), m_right(nullptr) {}
};
int main(){
Add add_op;
TreeNode * r0 = new TreeNode(add_op);
VarOperand d("d"), c("c"), b("b"), a("a");
TreeNode dnode(d);
r0->m_left = &dnode;
TreeNode add_node0(add_op);
r0->m_right = &add_node0;
}