Newsgroup: it.comp.lang.c++
Titolo: Informazioni su Protected e Extern

Salve,
il modificatore d'accesso protected rende accessibili i membri di una classe 
alle classi derivate. Perché il seguente codice da errore?
class X {
      protected :
      int a;  // Dice che a è inaccessibile in questo contesto.
};
class Y : public X {
      void f() {
           X x;
           x.a = 2;
      };
};
Inoltre vorrei sapere quando si usa extern.
Ho notato che se definisco una variabile in una header e lo includo nel file 
principale, la variabile è gia disponibile senza la necessita di usare 
extern, anzi se lo scrivo mi dice che non è possibile ridefinire la 
variabile. Ad es.:
// file header.h
int i = 3;
// file principale
#include <header.h>
extern int i = 5 // dovrebbe assegnare 5 alla i definita nell'header invece 
mi segnala errore.
int main() {
    cout << i << endl; // senza extern int i stampa 3 senza nessun errore.
}
Grazie 

 mi segnala errore.
Per il motivo che ho appena descritto. Avendo i inizializzata due
volte questo costituisce un tentativo di ridefinire i.
Queste sono nozioni basilari, spiegate su tutti i libri decenti. Se
non ce l'hai gia' ti consiglio di procurartene uno, in caso contrario
faresti bene a leggerlo meglio ;-)
Ciao,
Nicola

faresti bene a leggerlo meglio ;-)
Ho letto quello di Lippman e Stroustrup, ma solo una volta ciascuno, un po 
di tempo fa. Ora magari rivedo questo concetto.
Ciao 

presumibilmente non e' quello che vuoi.
Ma in pratica io volevo provare l'utilità di extern. Per caso in un 
eseguibile con un unico file header la keyword diventa inutile?
Come faccio a testarne l'utilità in maniera rapida? Bastano due header?
Ciao 

il tuo header.
[CUT]
Ho rivisto il testo di Stroustrup e in effetti c'e' scritto quello che dici
tu.
In pratica extern serve quando ci sono più file cpp. Infatti ho provato a
mettere
int i = 3 in un file cpp
e nell'altro file ho scritto extern int i senza la quale la compilazione non
va a buon fine.
Grazie

 X che fa parte dell'oggetto Y su cui sono chiamati. In soldoni
Uhm... perň
class X {
       protected :
       int a;
};
class Y : public X {
       void f() {
	   // X x;
            Y x;
            x.a = 2;
       };
};
compila senza errori col mio gcc nonostante che in x.a=2 si acceda ad un 
oggetto che non č quello su cui viene chiamato.
La differenza mi sembra piů sottile e, in effetti, non ne capisco molto 
il senso...
E.

 oggetto che non è quello su cui viene chiamato.
Probabilmente perché x essendo di istanza di Y viene considerato come 
istanza delle classe derivata stessa.
Ciao 

 il senso...
In buona sostanza la classe Y derivata da X può accedere ai membri 
protetti di ogni istanza di Y (o di classi derivate). E basta. In 
effetti HA senso. Se voglio incasinare i dati protetti di una classe X 
devo fare la mia estensione Y e prendermi tutte le responsabilità di 
quello che faccio. Le mie modifiche saranno accessibili solo tramite le 
istanze di Y. Il sistema assicura che chi invece accede agli elementi di 
tipo X non può incasinare lo stato interno.
E.

 oggetto che non è quello su cui viene chiamato.
In effetti ho scritto una cosa sbagliata. Lo standard dice questo
(11.5-1):
"Except when forming a pointer to member (5.3.1), the access must be
through a
pointer to, reference to, or object of the derived class itself (or
any class derived from that class) (5.2.5). If the access is to form a
pointer to member, the nested-name-specifier shall name the derived
class (or any class derived from that class)"
Cioe' il punto fondamentale e' che l'accesso avvenga tramite un
oggetto della classe derivata. Questo implica che l'accesso e'
limitato a quegli oggetti di tipo X che sono sotto-oggetti di oggetti
di tipo Y, ma non impone, come dicevo sbagliando, che l'accesso
avvenga tramite l'oggetto corrente.
Ciao,
Nicola