Newsgroup: it.comp.lang.c++
Titolo: Metodi d'accesso con const

Ho trovato sul Deitel un metodo d'accesso che utilizza due volte il 
qualificatore 'const':
// Begin
class MyClass {
public:
   // ...
   const char* getName() const { return name; }
private:
   char* name;
};
// End
Il const dopo getName() mi è chiaro, si usa quando il metodo è soltanto 
"ispettivo", cioè non modifica alcun membro privato.
Il const prima del char* non mi è chiaro.
Deitel dice che "il tipo restituito è const per evitare che il chiamante
possa modificare i dati private".
Come può il chiamante modificare i dati private se abbiamo già l'altro 
const dopo a destra?
Oppure è un modo per assicurare che il char* venga usato come rvalue?
Grazie in anticipo.

 const dopo a destra?
Il libro si riferisce alla manipolazione del valore restituito dal
metodo non a ciò che fa il metodo.
L'altro const non c'entra assolutamente nulla con il valore
restituito, mentre garantisce solo che il metodo non varia lo stato
della classe.

 Il const prima del char* non mi è chiaro.
La costanza attribuita al metodo MyClass::getName() dice che getName()
non può modificare gli elementi della classe, in particolare l'indirizzo
MyClass::name.
Ciò che è puntato da name non è necessariamente membro di MyClass.
Quindi, potresti usare MyClass::getName() per accedere a una stringa C e
modificarla, per esempio azzerandola:
*obj.getName() = '\0';
Molto probabilmente questo non è quello che vuoi fare: specificando che
il tipo restituito sia un const char*, imponi che chi chiama getName()
sia vincolato a non cambiare il valore da esso puntato, e la riga
scritta sopra non potrebbe venir compilata.
Dimostrazione: prova a compilare ciò che segue, con e senza il const
iniziale.
- ------------
class A
{
public:
        A() { name = new char[20]; }
        ~A() { delete[] name; }
        const char* getName() const {return name;}
private:
        char* name;
};
int main()
{
        *A().getName() = '\0';
        return 0;
}
- ------------
Ciao,
- -Federico
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.5 (GNU/Linux)
Comment: Using GnuPG with SUSE - 
http://enigmail.mozdev.org
iD8DBQFImdhrBIpu+y7DlLcRAkuQAJkBUPg5IGz4ekR9hTC4UwUjh5CSigCfbmrQ
rXMTkz1Q/0+d8QX+Lk3Ih5c=
=T6ti
-----END PGP SIGNATURE-----

         *A().getName() = '\0';
main.cpp|18|error: assignment of read-only location|
senza const, tutto ok

 della classe.
Ecco... una domanda che mi facevo č: lo stato della classe č soltanto 
l'insieme dei suoi membri dati o c'č anche altro che fa parte dello 
stato dell'istanza di una classe, e se sě cosa? Stato di eventuali 
membri stream ecc. ecc.?
Se la classe ha dei puntatori ad altri oggetti allocati dinamicamente, 
tali oggetti possono essere alterati da un membro const (posto di non 
toccare i puntatori)?

 toccare i puntatori)?
Il linguaggio non si lamenta. L'immagine a bit del nostro oggetto non č
dopotutto modificata. Viceversa lo stato interno potrebbe essere
modificato eccome.
Č insomma una falsa sicurezza: il compilatore fa un "certo" controllo,
che non necessariamente č quello che interessa al programmatore. Ancora
una volta sono l'attenzione e i test a fare la differenza (+ asserzioni,
contratti etc etc etc).
-- 
-riko

 contratti etc etc etc).
insomma, const, const... const 'na fava :-)
Niente di nuovo sotto il sole :-)


Non sono d'accordo. In C++ lo stato di un'istanza di una classe e'
dato dall'insieme dei suoi membri dato ed il qualificatore const sulle
funzioni membro specifica se dall'interno di una funzione membro e'
possibile o meno modificare il valore dei membri dato.
A livello di linguaggio questa e' l'unica definizione davvero utile
tra quelle possibili, perche' consente di implementare qualsiasi
alternativa si desideri sul piano concettuale/filosofico cui si
riferiva Enrico. Altrimenti a che punto dovrebbe fermarsi la
transitivita'? Ci sono davvero casi in cui avrebbe senso in una
funzione membro const impedire qualcosa come:
a->b->c->d->e->f->g = 42;
Nota che se linguaggi come Java e C# non hanno il const non e'
necessariamente perche' e' inutile. Anzi, a me pare che come concetto
combacerebbe abbastanza bene con la loro filosofia, solo che in
linguaggi fondati sui puntatori (pardon, riferimenti) non e'
implementabile in modo ragionevole.
Ciao,
Nicola

 Niente di nuovo sotto il sole :-)
Non capisco che cosa tu intenda dire. La parola chiave "const" ha un
suo significato e una sua utilità precisa.

 genere che ci sono i mutable. :P
Dal punto di vista filosofico (se proprio di filosofia si vuol
parlare), l'uso della lazy evaluation è comunque una forma di
inizializzazione. Seppure differita, è comunque una fase che non varia
propriamente lo stato dell'istanza, ma lo inizializza.