Newsgroup: it.comp.lang.c++
Titolo: come modellare le properties?

(scusate il metacodice in tutto il messaggio)
property, definizione: oggetto che contiene una variabile, o un
riferimento ad una variabile e che può essere modificato soltanto da
funzioni get e set, che eventualmente possono avere anche altri
effetti oltre al cambiamento della variabile
esempio:
property Width
è un intero, le due funzioni per leggere e modificare sono getWidth e
setWidth
quando io faccio
Width = 10;
in realtà sto chiamando la funzione setWidth(10);
questo è utile all'interno delle classi in cui è possibile avere
public:
property Width;
setWidth, getWidth;
private VWidth;
nel corpo di setWidth, quindi, andrà qualcosa del tipo:
setWidth(int Value)
{
	VWidth = Value;
}
come modellereste tutto ciò? avevo pensato ad un template, del tipo
property<int, getWidth, setWidth> Width;
si può fare? è meglio qualche altra scelta?
-- 
]\/[ad]\/[age (
www.mindreamz.net
)
"Un Maestro insegue semplicemente la sua visione di Eccellenza in
qualunque cosa sta facendo e lascia agli altri decidere se sta 
lavorando o giocando. A lui sembra sempre di fare entrambe." - Anonimo

 come modellereste tutto ciò? avevo pensato ad un template, del tipo
Uhm... io farei qualcosa del genere...
        template <class T>
        class Property {
        public:
                Property( ) { };
                virtual ~Property( ) { };
                const T& operator=( const Property& _p );
                Property& operator=( const T& _p );
                operator T( ) {
                        return get( );
 
                }
        protected:
                virtual const T& get( void ) const {
                        return value_;
                }
                virtual void set( const T& _value ) {
                        value_ = _value;
                }
        private:
                T       value_;
        };
        template< class T >
        const T& Property<T>::operator=( const Property& _p ) {
                return _p.get( );
        };
        template< class T >
        Property<T>& Property<T>::operator=( const T& _p ) {
                set( _p );
        }
In questo modo, se scrivi qualcosa del tipo:
        Property< int > pi;
        pi = 10; // 1
        cout << pi << endl; // 2
viene richiamato "set" per la riga (1), e "get" per la riga (2). Puoi 
ridefinire il comportamento di get/set derivando il template. Ad esempio,
        template <class T>
        class PropertyLimited : Property {
        public:
                PropertyLimited( const T& _min, const T& _max ) : 
                        min_( _min ), max_( _max ) { };
                virtual ~PropertyLimited( ) { };
        protected:
                virtual void set( const T& _value ) {
                        if ( _value < _min )
                                _value = _min;
                        else if ( _value > _max )
                                value_ = _max;
                        else
                                value_ = _value;
                }
        private:
                T       min_;
                T       max_;
        };
e quindi fare qualcosa del tipo:
        PropertyLimited< int > width( 0, 640 );
        ...
        width = 1024;
        cout << width << endl;
e ottenere come risultato "640".
Ciao!
 
-- 
---
*************** | Have you ever retired a human by mystake?
*** Azathot *** |
*************** | To contact me, ask me gently. Thanks.

 [...]
Sě, ma le property di solito sono membri di una certa classe, e quindi
sarebbe opportuno che i metodi get e set avessero accesso ai membri (sia
pubblici che privati) della classe stessa. Si dovrebbe quindi derivare una
classe property annidandola nella classe, e mantenere in essa un puntatore o
un riferimento alla classe "contenitrice", rendendo "friend" di quest'ultima
la classe property annidata. Tipo, se la classe si chiama MyClass:
template <typename T>
class MyProperty:public Property<T>{
    // ...
    MyProperty(MyClass* mc):mc(mc){}
    // ...
private:
    MyClass* mc;
}
--
imho

 o un riferimento alla classe "contenitrice", 
Uhmm... e fare una cosa del genere?
        classe SonoUnaClasse {
        public:
                Property< int > membro_;
        }
Cioè, in questo modo sposti la responsabilità del trattamento dell'attributo 
"membro_" da "SonoUnaClasse" alla classe "Property". Il problema è che, in 
effetti, questo approccio "mostra" dettagli della classe. D'altronde, però, 
le Property forse hanno senso solo se sono raggiungibili direttamente...
