I cannot build an Expression Tree Node that follows the Open/Close Principle

40 Views Asked by At

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;
}
0

There are 0 best solutions below