    #include <string>
    #include <map>
    #include <iostream>

    using namespace std;

    class Okolina
    {
    public:
    	double VrednostPromenljive( const string& s ) const
    		{
    		map<string,double>::const_iterator
    			f = _Promenljive.find(s);
    		if( f != _Promenljive.end() )
    			return f->second;
    		else{
    			// ovde bi trebalo da se napravi izuzetak
    			return 0;
    			}
    		}

    	bool DefinisanaPromenljiva( const string& s ) const
    		{
    		map<string,double>::const_iterator
    			f = _Promenljive.find(s);
    		return f != _Promenljive.end();
    		}

    	void DodajPromenljivu( const string& s, double v )
    		{ _Promenljive[s] = v; }

    private:
    	map<string,double> _Promenljive;
    };

    class Izraz
    {
    public:
    	virtual ~Izraz()
    		{}
    	virtual double Vrednost( const Okolina& o ) const = 0;
    	virtual void Ispisi( ostream& ostr ) const = 0;
    };

    ostream& operator << ( ostream& ostr, const Izraz& i )
    {
    	i.Ispisi( ostr );
    	return ostr;
    }

    class Konstanta : public Izraz
    {
    public:
    	Konstanta( double d )
    		: _Vrednost(d)
    		{}

    	double Vrednost( const Okolina& o ) const
    		{ return _Vrednost; }

    	void Ispisi( ostream& ostr ) const
    		{ ostr << _Vrednost; }

    private:
    	double _Vrednost;
    };

    class Promenljiva : public Izraz
    {
    public:
    	Promenljiva( const string& s )
    		{}

    	double Vrednost( const Okolina& o ) const
    		{ return 0; }
    };

    class Zbir : public Izraz
    {
    public:
    	Zbir( Izraz* i1, Izraz* i2 )
    		{}

    	double Vrednost( const Okolina& o ) const
    		{ return 0; }
    };

    main()
    {
    	Okolina o;
    	o.DodajPromenljivu( "x", 5 );

    	// izraz (x+2)
    //	Izraz* i1 = new Zbir( new Promenljiva("x"), new Konstanta(2));
    	Izraz* i1 = new Konstanta(2);
    	cout << (*i1) << " = " << i1->Vrednost( o ) << endl;
    	delete i1;

    	return 0;
    }