Newsgroup: it.comp.lang.c++
Titolo: Variaibili private e variabili pubbliche di una classe

Ciao!
Leggendo la guida di Visual C++ .NET, ho trovato il seguente esempio:
class Point
{
public:
    // Define "accessor" functions as
    //  reference types.
    unsigned& x();
    unsigned& y();
private:
    unsigned _x;
    unsigned _y;
};
inline unsigned& Point::x()
{
    return _x;
}
inline unsigned& Point::y()
{
    return _y;
}
void main()
{
}
Che differenza c'è tra prevedere questo metodo per accedere alle variabili
private _x e _y, e definire direttamente tali variabili come pubbliche?
Grazie di cuore per l'attenzione.
Riccardo.

1) questo è un ng di c++ standard, non di .net... comunque
2) a mio parere, ma altri sapranno dirti meglio, non solo non ha senso
fare quello che c'è nell'esempio, ma è anche un cattivo esempio di
programmazione... se una variabile è privata deve essere privata... in
quel modo permetti a chi usa la classe di accedere direttamente a
elementi privati... altro discorso si poteva fare se le due funzioni
erano definite come const unsigned& x()... in questo modo si creavano
delle variabili di "sola lettura"... il che era sensato
3) a proposito di definizioni... unsigned COSA? lo standard non
permette di non indicare di quale tipo si tratti (immagino di default
sia int, ma lo standard vuole che tu lo scriva)
-- 
]\/[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

 sia int, ma lo standard vuole che tu lo scriva)
<domanda_retorica>
 hai controllato prima di citarlo come riportato dallo standard, vero?
</domanda_retorica>
-- 
sbirish


wrote:

gcc quando compila una cosa del genere dice "lo standard non permette
una dichiarazione priva di tipo" o qualcosa del genere
lo standard non l'ho controllato, ma ipotizzo che se gcc dice qualcosa
dello standard, lo dica con criterio


 dello standard, lo dica con criterio
lo standard dice chiaramente che è valido.
<cite from="ISO/IEC 14882:1998(E)" 
  par="7 Declarations 7.1.5.2 Simple type specifiers">
 Table 7 simpletypespecifiers and the types they specify
 Specifier(s)   |  Type
 typename       |  the type named
 ---------------|--------------------
 char           |  "char"
 unsigned char  |  "unsigned char"
 signed char    |  "signed char"
 bool           |  "bool"  
 unsigned       |  "unsigned int"
 ^^^^^^^^
 unsigned int   |  "unsigned int"
 signed         |  "int"
 ^^^^^^
 signed int     |  "int"
</cite>
e neanche gcc si lamenta.
sbirish@sophia sbirish $ cat crap.cpp
#include <iostream>
int main()
{
    signed a(-9);
    unsigned b(10);
    std::cout << a <<" "<< b <<" "<< std::endl;
}
sbirish@sophia sbirish $ g++ -o crap crap.cpp -Wall
sbirish@sophia sbirish $ ./crap
-9 10
sbirish@sophia sbirish $
-- 
sbirish

 come pubbliche?
Le variabili pubbliche fanno parte dell'interfaccia, e non le puoi
cambiare senza cambiare anche tutti i propgrammi che usano la classe.
Con questo metodo puoi cambiare l'implementazione della classe senza
perdere la compatibilita` con i programmi che usano x() e y(), anche
se in maniera scomoda e contorta.
Per esempio supponiamo che x() e y() siano in metri, e vogliamo
cambiare la rappresentazione interna da metri a millimetri.
Nella nuova classe la versione non-const di x() e y() invece di
restituire un riferimento a una variabile interna, restituisce una
classe che simula un riferimento.
  class Point
  {
    class XRef {
      Point & _point;
    public:
      explicit XRef(Point & point) : _point(point) {}
      operator int () const { return _point._x_mm / 1000; }
      int operator = (int x) { _point._x_mm = x * 1000; return x; }
    };
    friend class XRef;
    class YRef { ... };
  public:
    Point(int x, int y) : _x_mm(x*1000), _y_mm(y*1000) {}
    // la versione const restituisce un valore
    int x() const { return _x_mm / 1000; }
    int y() const { return _y_mm / 1000; }
    // la versione non-const restituisce un finto riferimento
    XRef x() { return XRef(*this); }
    YRef x() { return YRef(*this); }
  private:
      int _x_mm;
      int _y_mm;
  };
  int main()
  {
    Point p(3, 4);
    cout << p.x() << " " << p.y() << "\n";
    p.x() = 5;
    cout << p.x() << " " << p.y() << "\n";
  }
Nell'esempio XRef implementa solo l'assenamento, ma si puo` aggiungere
altra roba e supportare x()++ e simili.
Naturalmente se la classe fossa stata progettata bene dall'inizio
senza esporre al pubblico le variabili private, sarebbe stato tutto
piu` semplice.
        Mauro