Newsgroup: it.comp.lang.c++
Titolo: puntatore a classe

Salve a tutti, ho iniziato a studiare il polimorfismo, e non capisco una 
cosa. Perchè se tento di accedere direttamente con un puntatore ad una 
classe il programma si blocca? Se prima dichiaro un'oggetto di quella 
classe, poi assegno al puntatore l'indirizzo dell'oggetto, raggiungo i 
metodi della classe senza problemi, ma credevo si potesse fare anche 
l'operazione che ho descritto prima. Posto i due sorgenti.
Funziona:
#include<iostream>
using namespace std;
class padre
{
 public: virtual void chi_sono(); //parola chiave "virtual" metodo virtuale
};
class figlio:public padre
{
 public:void chi_sono();
};
main()
{
 padre primo;  //creo oggetto di classe padre
 padre *puntatore;  //creo puntatore a oggetto padre
 primo.chi_sono();  //chiamo metodo della classe padre: ritorna "sono il 
padre"
 puntatore=&primo; //passo a puntatore al padre indirizzo del padre
 puntatore->chi_sono(); //punto metodo della classe padre: ritorna "sono il 
padre"
 figlio secondo; //creo oggetto di classe figlio
 secondo.chi_sono(); //chiamo metodo della classe figlio: ritorna "sono il 
figlio"
 puntatore=&secondo; //passo a puntatore al padre indirizzo del figlio
 puntatore->chi_sono(); //chiamo metodo della classe figlio: ritorna "sono 
il figlio"
 cin.get();
}
void padre::chi_sono()
{
 cout<<"\n\nsono il padre";
}
void figlio::chi_sono()
{
 cout<<"\n\nsono il figlio";
}
si blocca:
#include<iostream>
using namespace std;
typedef class padre
{
 public: virtual void chi_sono(); //parola chiave "virtual" metodo virtuale
};
class figlio:public padre
{
 public:
 void chi_sono();
 int a;
};
main()
{
 figlio *puntatore;
 puntatore->chi_sono();
 cin.get();
}
void padre::chi_sono()
{
 cout<<"\n\nsono il padre";
}
void figlio::chi_sono()
{
 cout<<"\n\nsono il figlio";
}
Grazie a tutti in anticipo.

  puntatore->chi_sono();
Qui accedi all'oggetto puntato da tale puntatore. Ma dato che il 
puntatore non e' stato inizializzato ne' ha mai ricevuto un valore, il 
comportamento di questa operazione non e' definito dal linguaggio. 
Spesso genera un errore in fase di esecuzione che porta alla 
terminazione del programma.
-- 
     Carlo Milanesi
 
http://digilander.libero.it/carlmila

 terminazione del programma.
Per inizializzarlo cosa intendi? Assegnargli un indirizzo? Avevo già provato 
in un programma (però in linguaggio C) ad accedere tramite puntatore alle 
variabili di una struttura (avendole definite in precedenza con typedef, e 
quindi definendo un nuovo tipo) senza problemi. Con le classi è forse 
differente? Non sono sempre strutture, con l'aggiunta di metodi? Oppure è il 
C++ che non prevede questo comportamento? Grazie per la risposta. 

 C++ che non prevede questo comportamento?
In C++, come in C, si puo' accedere ai campi di una struttura usando un 
puntatore alla struttura e l'operatore "->". Lo stesso vale per le 
classi, purche' si abbia diritto di accesso a tali membri (per es. siano 
"public").
Comunque sia in C che in C++ tale operazione e' errata se il puntatore 
non punta effettivamente a un oggetto del tipo corretto.


 Per inizializzarlo cosa intendi? Assegnargli un indirizzo? 
Devi comprendere bene la differenza tra l'istruzione
figlio f;
e l'istruzione
figlio* puntatore;
La prima istruzione dichiara una variabile di tipo figlio. Questa
dichiarazione *istanzia* implicitamente un oggetto di tipo "figlio" 
sullo stack (se non sai cos'è vattelo a vedere assolutamente), chiamando 
il costruttore di default della classe figlio. Nel caso tu avessi un 
costruttore che prende un parametro potresti anche scrivere
figlio f(x);
La seconda istruzione esegue un'operazione analoga ma il tipo questa 
volta è "puntatore a figlio". Quindi sullo stack viene "istanziato" un 
puntatore a figlio, non un oggetto di tipo figlio. Essendo "puntatore" 
un tipo base non avviene nessuna chiamata a costruttore. Semplicemente 
questo puntatore si ritroverà un valore non definito, su cui non si può 
fare alcuna assunzione. Come ben saprai
un puntatore è una variabile che contiene un indirizzo di memoria.
Affinchè tu possa accedere ai membri di un oggetto del tipo puntato (in 
questo caso "figlio"), questo indirizzo deve essere quello di un oggetto
di quel tipo. Ecco perchè il tuo programma "si blocca".
E' corretto invece fare
figlio f;  <---Istanzia oggetto di tipo "figlio"
figlio* x = &f; <---Assegna al puntatore l'indirizzo dell'oggetto 
istanziato.
ciao