Newsgroup: it.comp.lang.c++
Titolo: utilita' del const

Vorrei proporvi una riflessione critica. Qual'e' l'utilita dei parametri
e delle funzioni membro const in rapporto al maggior lavoro che
comportano nella stesura del codice?
Ad esempio, nel codice che segue ho definito due versioni della stessa
funzione, una che permette un accesso in lettura e scrittura, e l'altra
per l'accesso in sola lettura. La seconda serve per supportare i casi in
cui il CBoardStatus sia const. 
class CBoardStatus
{
	public:
		// ...
		float& tanksOf (int inTerritory);
		float tanksOf (int inTerritory) const;
		// ...
};
Ma eliminando questi casi, elimino la seconda funzione e quindi
semplifico il codice,  operazione che va a discapito di un elemento di
controllo. Ma questo elemento di controllo e' realmente utile?

controllo. Ma questo elemento di controllo e' realmente utile?
Nella mia esperienza, si`.  Ho programmato con linguaggi il
cui concetto di "tipo" era vaghissimo o assente (Fortran,
assembler, Rexx, Perl...) e altri in cui era rigidissimo (Modula-2,
Pascal/VS -- entrambi includono il concetto di parametro
const), e ho verificato di persona (rispetto al mio "stile" e
a quello "medio" dei colleghi, e rispetto a una notevole
varieta` di campi di applicazione dei programmi) che, per
me, la tipizzazione piu` precisa, const incluse, e` MOLTO,
MOLTO benefica.  Tot errori beccati gia` dal compilatore,
tot interventi di manutenzione cannati in meno, tot (poche,
purtroppo -- molti compilatori che ho usato non avevano a
disposizione i migliori ottimizzatori del mondo:-) chance di
ottimizzazione del mio codice per il compilatore.
Altri programmatori, incluso alcuni che stimo, si trovano
invece molto piu` a proprio agio, e si ritengono maggiormente
produttivi, con linguaggi a tipizzazione debole o assente --
e, per fortuna (almeno quelli che stimo) usano, appunto,
linguaggi di questa categoria, tipo Smalltalk.
Quello che secondo me non puo` mai essere un approccio
vincente e` scegliere un linguaggio che ha certe proprieta`
che lo caratterizzano fortemente (tipizzazione rigida, ovvero
sua assenza) e poi _combattere_ questa caratteristica
fondamentale del linguaggio invece che trarne i benefici
che puo` dare -- cercare di fare programmazione a tipi
rigidi in Smalltalk, o di ignorare il type-system del C++ (si`,
const inclusa).  E` curioso che succeda cosi` spesso.
Alex

 Nella mia esperienza, si`.
[SNIP]
Il mio era un dubbio di fede. Quando ho iniziato a programmare in c++ ho
avuto non poche difficolta' ad adattarmi ai const. Adesso li uso con
disinvoltura. Ho pero' notato come a volte il const ti costringa a fare
lavoro in piu'. Normalmente definisco parametri e funzioni const
coerentemente con la loro semantica. Ma questa mattina, mentre facevo
lavoro di copia ed incolla per definire la versone const e quella non di
diverse funzioni membro, mi sono chiesto se queste operazioni fossero
utili. Come hai visto nel messaggio precedente, la funzione era la
stessa ma definita in due modi diversi a seconda che fosse usata in
lettura o in scrittura. Ho avuto modo di riflettere e penso sia meglio
cambiare la prima funzione da
	float& tanksOf (int inTerritory);
a
	void setTanksOf (int inTerritory, float inTanks);
In effetti cosi' c'e' una netta distinzione tra le due operazioni. In
piu', c'e' da fare un'altra considerazione. Nel codice mostrato non
c'era l'implementazione.
	float& CBoardStatus::tanksOf (int inTerritory) {
		return mTanks [inTerritory];
	}
	float CBoardStatus::tanksOf (int inTerritory) const {
		return mTanks [inTerritory];
	}
Guardandola si puo' notare come abbia utilizzato le due funzioni per
pubblicare indirettamente un membro privato della classe. L'utilizzo di
funzioni di tipo get e set mi sembra IMHO piu' corretto.
Ciao.
P.S.: Chissa' perche', ma mi vengono in mente i messaggi d'errore del
compilatore C del MPW di Apple, che tradotti somiglierebber a questo:
"Come, cosa, ma tu vuoi veramente che compili questo!?". Oppure: "troppi
errori in questo file, fanne meno!"

funzioni di tipo get e set mi sembra IMHO piu' corretto.
Stai decisamente piu` tranquillo, si`.  Inoltre, come da mio
recente post a comp.lang.c++.moderated, stai molto piu`
tranquillo se eviti di dare lo stesso nome a due funzioni il
cui scopo e` rispettivamente di leggere, e di scrivere, un
certo dato -- lo so che i "cattivi esempi" (accessori e
mutatori overloaded sullo stesso nome) si trovano persino
nella libreria standard C++ (ad es., la rdbuf() degli stream),
ma ci sono tante ragioni per evitare questo stile a favore di
una scelta di nomi del tipo setPippo/getPippo:
    1. si puo` prendere l'indirizzo (pointer-to-member) di una
        funzione-membro piu` agevolmente,
    2. si evitano problemi da "override/hiding" parziale,
    3. si evita di solleticare certi bug di compilatori molto diffusi
per citare solo alcuni "dati obbiettivi" (non vi e` alcun
"contrappeso" a questi, sull'altro piatto della bilancia; cioe`,
estetica a parte, l'overload non ha nessun vantaggio sul
piano "obbiettivo", solo svantaggi).
Alex


Non sono normalmente d'accordo all'uso di metodi get/set,
e` esattamente lo stesso che rendere un membro public
anzicche` private. Trovo che l'uso di simili tecniche sia poco
corretto (da un punto di vista OO) e valido solo in rarissime occasioni.
Ultimamente ad esempio ne ho fatto uso in un programma di drawing
in cui la  modifica da parte dell'utente del solo colore di un oggetto era un'operazione
assolutamente normale, in questo caso l'uso di get/set mi ha permesso l'implementazione
di un controllo sul valore assegnato e l'introduzione di uno strato intermedio tra il
concetto di colore e la sua rappresentazione all'interno dell'oggetto.
Saluti,
Paolo