Newsgroup: it.comp.lang.c++
Titolo: Classi definite all'interno di altre classi

Ciao a tutti.
Ho una domanda da sottoporvi:
se ho il seguente codice:
class X {
   //..........
   class Y {  /*........  */ } y_member;
 public:
   //.......
};
posso istanziare un oggetto di tipo X::Y?
Visual C++ non me lo consente, g++ sotto Linux sě.
Per contro con g++ non mi č possibile definire, all'esterno della classe X,
dei membri di X che restituiscano un oggetto Y, ad es:
X::Y X::ret_y_member { return y_member; }
Qui VC++ funziona, mentre g++ si arrabbia, a meno che non cambi il prototipo
in
X::Y& X::ret.......
In parole povere, g++ mi consente la definizione di tale membro solo
all'interno della classe di appartenenza (booh!!!), mentre VC++ lo permette
anche all'esterno, ma non mi permette di istanziare un oggetto X::Y, mentre
g++ sě.
Che cosa ne pensate?
Ciao
Domenico Barra

 wrote in message
QA4C5.63895$3R6.1...@news.infostrada.it...

Non conosco g++ quindi ti rispondo in merito al Visual C++.
Nella classe X non hai specificato il criterio di accesso della classe Y che
di default č private.
Percui al di furi della classe X , Y non risulta visibile.
Se la classe X del tuo esempio la dichiari nel seguente modo:
class X {
    //..........
public:
    class Y {  /*........  */ };
private:
     Y y_member;
  public:
    //.......
};
il compilatore non si arrabbia se cerchi di istanziare un oggetto X::Y al di
fuori della classe X.
Porlock.

fuori della classe X.
Già, questo l'avevo già capito, e il dilemma è proprio questo: le classi
definite in ambito private di una altra classe possono essere istanziate per
conto proprio? (e non vedo perché non dovrebbero, visto che comunque non
sarebbe possibile alterare un eventuale membro private). E' un punto su cui
nessuna fonte (nemmeno Stroustrup!!!) mi dà delucidazioni :-(
Ciao
Domenico Barra

 [CUT]
Il seguente codice funziona (come deve) con il BCC 5.5:
class X
{
  private:
     class Y
     {
        private:
          int x;
        public:
          Y(int xx)
          : x(xx) {  }
     } y_member;
  public:
     X(int x)
     : y_member(x) {  }
     Y ret_y_member() const { return y_member; }
};
int main()
{
   X x(3);
   x.ret_y_member();
   X::Y y = x.ret_y_member();  // ERRORE: X::Y non accessibile
}
Manlio Perillo

 Che cosa ne pensate?
hai provato a vedere nella lista dei known bug di g++?





  public:
     X(int x)
     : y_member(x) {  }

int main()
{
   X x(3);
   x.ret_y_member();

   X::Y& yr =  x.ret_y_member();  // ERRORE: X::Y non accessibile
}
Se si rende Y publico non si ha più nessun errore
Manlio Perillo


C'è qualcosa sia sul Lippman che sul libro di Eckel, dicono più o meno le
stesse cose, e cioè
che nelle classi nidificate valgono le regole di visibilità.
Sul libro di Eckel c'è una precisazione che informa che questo comportamento
può essere soggetto
allo standard del compilatore; riporto quanto è scritto:
"Le classi annidate sono implementate diversamente nelle differenti versioni
del C++.
I compilatori conformi alla versione pre-AT&T 2.0 non permettono le classi
annidate;
i compilatori conformi alla versione AT&T 2.0 permettono l'annidamento, ma
la classe annidata viene
trattata come se fosse stata dichiarata globalmente; i compilatori conformi
alla versione AT&T 2.1 e successive, trattano la classe annidata come ci si
aspetta dalla sua sintassi: la dichiarazione della classe è un elemento
della classe che la contiene, ed è soggetta alle regole di visibilità e di
privatezza defli altri elementi della classe."
Porlock.


Grazie mille, sei stato davvero gentile!
Ciao ;-)
Domenico Barra

 X::Y& X::ret.......
strano, hai provato a dare un occhio alla lista dei bug conosciuti del g++?
mi pareva di avere letto proprio una cosa del genere....

conto proprio?
Certo, pero` essendo dichiarate nella sezione private di X puoi
istanziarle ed utilizzarle solo entro i metodi di X.
Paolo

 mi pareva di avere letto proprio una cosa del genere....
e infatti, ecco:
G++ allows to access private types
GCC 2.95 incorrectly accepts code like
struct X{
 private:
   struct Y{};
};
X::Y z;
Since Y is a private member of X, the definition of z should be rejected,
but isn't. This applies to structs, classes and types in general; for other
members of classes (functions and data), access control is implemented.
In the development branch of GCC, this bug was fixed on Feb 7, 2000. The fix
will appear in the next major release of GCC (after 2.95).
... quindi č un bug del compilatore
--
Posted from [213.82.54.99] 
via Mailgate.ORG Server - 
http://www.Mailgate.ORG