#include <iostream>
#include <cstdlib>

using namespace std;

class Nodo {
     public:
        virtual double eval() const = 0;
        virtual ~Nodo() {};
};

class Cte : public Nodo {
    private:
       double val;

    public:
       Cte(double v= 0);
       virtual double eval() const;
       virtual ~Cte();
};
 
Cte::Cte(double v)
{
   val= v;
}

double Cte::eval() const
{
   return val;
}

Cte::~Cte()
{
    cerr << "destruyendo constante\n";
}

class Sum : public Nodo {
    private:
       Nodo* izq;
       Nodo* der;
    public:
       Sum(Nodo* i, Nodo* d);
       virtual ~Sum();
       virtual double eval() const;
        
};

Sum::Sum(Nodo* i, Nodo* d)
{
   izq= i;
   der= d;
}

double Sum::eval() const
{
   return izq->eval() + der->eval();
}

Sum::~Sum()
{
    cerr << "destruyendo suma\n";
    delete der;
    delete izq;
}
  
 
class Pro : public Nodo {
    private:
       Nodo* izq;
       Nodo* der;
    public:
       Pro(Nodo* i, Nodo* d);
       virtual ~Pro();
       virtual double eval() const;
        
};

Pro::Pro(Nodo* i, Nodo* d)
{
   izq= i;
   der= d;
}

double Pro::eval() const
{
   return izq->eval() * der->eval();
}
  
Pro::~Pro()
{
    cerr << "destruyendo producto\n";
    delete der;
    delete izq;
}
  
 
int main(int argc, char* argv[])
{
    Nodo*  p= new Cte(8);
    Nodo*  q= new Cte(5);
    Nodo*  s= new Sum(p, q);
    Nodo*  t= new Cte(3);
    Nodo*  r= new Pro(t, s);

    cout << "p(8)= " << p->eval() << endl;
    cout << "q(5)= " << q->eval() << endl;
    cout << "s(p+q)= " << s->eval() << endl;
    cout << "t(3)= " << t->eval() << endl;
    cout << "r(t*(p+q))= " << r->eval() << endl;

    delete r;

    return EXIT_SUCCESS; 
}


