#include class Expr { public: virtual void print(std::ostream&) = 0; virtual ~Expr() { } }; class IntExpr: public Expr { public: IntExpr(int n0): n(n0) { } void print(ostream& s) { s << n; }; private: int n; }; class UnaryExpr: public Expr { public: UnaryExpr(const char* s, Expr* e0): op(s), e(e0) { } void print(ostream& s) { s << "(" << op; e->print(s); s << ")"; } ~UnaryExpr() { delete e; } private: Expr* e; const char* op; }; class BinaryExpr: public Expr { public: BinaryExpr(const char* s, Expr* e01, Expr* e02): op(s), e1(e01), e2(e02) { } void print(ostream& s) { s << "("; e1->print(s); s << op; e2->print(s); s << ")"; } ~BinaryExpr() { delete e1; delete e2; } private: const char* op; Expr* e1; Expr* e2; }; int main() { Expr* three = new IntExpr(3); Expr* four = new IntExpr(4); Expr* five = new IntExpr(5); Expr* negfive = new UnaryExpr("-", five); Expr* twelve = new BinaryExpr("*", three, four); Expr* seven = new BinaryExpr("+", negfive, twelve); seven->print(cout); }