#include <iostream>
 
// Asi es en C++
 
typedef int Valor;
 
struct Nodo
{
    Valor dato;
    Nodo* abajo;
};
 
class Pila
{
public:
    Pila() : pNodoSuperior(0) {}
 
    ~Pila()
    {
        limpiar();
    }
 
    Pila(const Pila& p) : pNodoSuperior(0)
    {
        *this = p;
    }
 
    const Pila& operator=(const Pila& p)
    {
        limpiar();
        Nodo* pNodoActual = p.pNodoSuperior;
        while (pNodoActual)
        {
            push(pNodoActual->dato);
            pNodoActual = pNodoActual->abajo;
        }
        invertir();
        return *this;
    }
 
    void limpiar()
    {
        Nodo* pNodoTemp;
        while (pNodoSuperior)
        {
            pNodoTemp = pNodoSuperior;
            pNodoSuperior = pNodoSuperior->abajo;
            delete pNodoTemp;
        }
    }
 
    bool push(const Valor& val)
    {
        Nodo* pNuevoNodo = new (std::nothrow) Nodo;
        if (0 == pNuevoNodo) return false;
        pNuevoNodo->abajo = pNodoSuperior;
        pNuevoNodo->dato = val;
        pNodoSuperior = pNuevoNodo;
        return true;
    }
 
    bool pop(Valor& val)
    {
        if (0 == pNodoSuperior) return false;
        Nodo* pNodoDesechado = pNodoSuperior;
        pNodoSuperior = pNodoSuperior->abajo;
        val = pNodoDesechado->dato;
        delete pNodoDesechado;
        return true;
    }
 
    void invertir()
    {
        Nodo* pNodoActual = pNodoSuperior;
        Nodo* pNodoArriba = 0;
        Nodo* pNodoAbajo;
        while (pNodoActual)
        {
            pNodoAbajo = pNodoActual->abajo;
            pNodoActual->abajo = pNodoArriba;
            pNodoArriba = pNodoActual;
            pNodoActual = pNodoAbajo;
        }
        pNodoSuperior = pNodoArriba;
    }
 
    void mostrar() const
    {
        std::cout << "Pila: ";
        Nodo* pNodoTemp = pNodoSuperior;
        while (pNodoTemp)
        {
            std::cout << " " << pNodoTemp->dato;
            pNodoTemp = pNodoTemp->abajo;
        }
        std::cout << std::endl;
    }
 
private:
    Nodo* pNodoSuperior;
 
};
 
int main()
{
    Pila p;
    p.push(1);
    p.mostrar();
    p.push(2);
    p.mostrar();
    p.push(3);
    p.mostrar();
    p.push(4);
    p.mostrar();
    Valor v;
    
    Pila p1(p);
 
    p.pop(v);
    p.mostrar();
    p.pop(v);
    p.mostrar();
    p.pop(v);
    p.mostrar();
    p.pop(v);
    p.mostrar();
 
    p1.mostrar();
    p1.invertir();
    p1.mostrar();
 
    // Pausa
    char c[1];
    std::cin.getline(c, 1);
}