Newsgroup: it.comp.lang.c++
Titolo: Una questione di forma o di sostanza?

Diciamo che ho una classe con questa variabile:
class MyClass
{
private:
  bool isOnline_;
}
che voglio poter settare e recuperare tramite un qualche metodo
pubblico. Come metodi, scrivereste piu' una cosa cosi':
void setOnline()		{ isOnline_ = true; }
void setOffline()		{ isOnline_ = false; }
bool isOnline() const	{ return isOnline_; }
o cosi':
bool & isOnline()		{ return isOnline_; }
Cioe': metodi separati per settare e recuperare i dati, o uno solo che
restituisce una referenza (per poterlo usare sia per settare che per
ottenere il valore)?
Pleg

 bool & isOnline()		{ return isOnline_; }
Quest'ultima soluzione equivale sostanzialmente a rendere pubblica la 
variabile. E' vero che in teoria questo metodo potrebbe essere 
modificato in seguito, ma non si potra' mai distinguere quando viene 
usato per leggere la variabile e quando per scriverla. Quindi mi sembra 
del tutto inutile.
Io consiglio di distinguere le proprie classi in due categorie:
- Quelle che incapsulano le variabili.
- Quelle che non incapsulano le variabili.
Le classi che incapsulano le variabili sono dichiarate con la 
parola-chiave "class" e hanno tutte le variabili membro "private" (non 
"protected").
Le classi che non incapsulano le variabili sono dichiarate con la 
parola-chiave "struct" e non usano mai gli specificatori di accesso 
("public", "protected", "private"), e percio' hanno tutte le variabili 
membro pubbliche.
Un incapsulamento corretto delle variabili deve consentire 
all'implementatore della classe di distinguere quando l'utente della 
classe sta leggendo o sta scrivendo la variabile.
Anche Scott Meyers in "Effective C++ - Third Edition", scrive:
     Item 28: Avoid returning "handles" to object internals.
L'unico caso in cui io (come Meyers) considero opportuno fornire un 
riferimento a una variabile privata e' l'operatore [] per accedere ai 
campi di un array membro.
 > void setOnline()		{ isOnline_ = true; }
 > void setOffline()		{ isOnline_ = false; }
Invece di fare due metodi farei un metodo solo.
void setOnline(bool value = true) { isOnline_ = value; }
-- 
Carlo Milanesi
http://digilander.libero.it/carlmila

 void setOnline(bool value = true) { isOnline_ = value; }
Concordo. Lascerei anche i due metodi se e solo se si usa molta
programmazione funzionale su oggetti di quel suo tipo e contenitori
standard. Ci si salva da un po' di usi di bind che rompono le palle. :)
-- 
-riko


Farei cosi`
class MyClass
{
public:
	/* Costruttore di default che inizializza tutte le variabili
	proprie ad uno stato noto (valuta se meglio true o false a
	seconda del caso pratico */
	MyClass() {isOnline_ = false}
	/* Costruttore che preinizializza la variabile come richiesto */
	MyClass(bool x) {isOnline_ = x;}
	/* Distruttore virtuale standard, lo puoi omettere per
	efficienza se non prevedi il polimorfismo */
	virtual ~MyClass() {}
	/* Funzione per impostare il valore, con il nome della
	"proprieta" prefissato da "do" (set/get ; do/is) */
	void doOnline(bool x) {isOnline_ = x;}
	/* Funzione per ottenere il valore della "proprieta",
	attenzione al const ! */
	bool isOnline() const {return isOnline_;}
private:
	bool isOnline_;
}
Con il tipo bool e` inutile usare le reference perche` e` un tipo
scalare la cui copia e` confrontabile con la copia di un puntatore.
Di solito uso le reference per le classi/struct e il tipo semplice per
gli scalari.

Grazie a tutti!
Pleg

         void doOnline(bool x) {isOnline_ = x;}
Ah, ecco, non avevo mai trovato una parola complementare per "is", per
avere la simmetria... "do" mi sembra adeguato, thx!
Pleg

 wrote:

A me pero' non piace. Normalmente quello si chiama setOnline, e' un
classico 'setter'. Brutto o bello e' piuttosto standard come
nomenclatura. 
Io i do li uso in altre situazioni.
-- 
-riko

 
In questo caso � veramente una questione molto formale e poco sostanziale.
Ma in generale per inizializzare le variabili membro nei casi "semplici" 
secondo tutti gli autori � meglio abituarsi ad utilizzare le init-list:
  	MyClass() : isOnLine_(false) {}
  	MyClass(bool x) : isOnline_(x) {}
Per maggiori info vedere ad es.
http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.6
Beppe