PDA

View Full Version : [C++] Allocazione dinamica con puntatore


leon84
25-05-2007, 20:13
Salve,
aiutatemi a comprendere meglio quanto segue :

Date :


Class B {

public :
int a,b;
void f();
}

Class D : public B {

public:
int c,d;
void f();

}

int main() {

D d;
B* p = new D;

}


L'istruzione "B* p = new D;" , corregetemi se sbaglio, alloca uno spazio di memoria per ospitare tutti i membri della classe D e l'indirizzo di tale allocazione è passato a p. Il punto però è che p non è dello stesso tipo ma della classe base.

Ora mi chiedo : in memoria c'è cmq tutto D soltanto che il puntatore p può referenziare soltanto la parte B della classe D. Dico bene ?

Nel momento in cui p volesse referenziare tutto D come faccio ? Dovrei, penso effettuare un casting di p da B* a D*. ma come ?

se eseguo :

D* pb=static_cast<D*>p;

in questo modo col puntatore pb riesco a referenziare la parte mancante della classe D che era impossibilitato da p ?

marco.r
25-05-2007, 20:35
Salve,
aiutatemi a comprendere meglio quanto segue :

Date :


Class B {

public :
int a,b;
void f();
}

Class D : public B {

public:
int c,d;
void f();

}

int main() {

D d;
B* p = new D;

}


L'istruzione "B* p = new D;" , corregetemi se sbaglio, alloca uno spazio di memoria per ospitare tutti i membri della classe D e l'indirizzo di tale allocazione è passato a p. Il punto però è che p non è dello stesso tipo ma della classe base.

Ora mi chiedo : in memoria c'è cmq tutto D soltanto che il puntatore p può referenziare soltanto la parte B della classe D. Dico bene ?

Nel momento in cui p volesse referenziare tutto D come faccio ? Dovrei, penso effettuare un casting di p da B* a D*. ma come ?

se eseguo :

D* pb=static_cast<D*>p;

in questo modo col puntatore pb riesco a referenziare la parte mancante della classe D che era impossibilitato da p ?
L'idea e' corretta, solo che al posto di static_cast devi usare dynamic_cast, in quanto solo durante l'esecuzione del programma hai modo di capire se l'oggetto p e' effettivamente di tipo D oppure e' un'altra classe.

leon84
25-05-2007, 20:40
Quindi se avevo inizializzato con un costruttore gli attributi c e d della classe D dopo il casting riuscirei comunque a referenziarli e trovarci i valori di inizializzazione grazie al puntatore pb ?

leon84
25-05-2007, 20:45
Mi è venuto un ennesimo dubbio:

metti che ho:


void g (B& b) {
b.f();
}

int main() {

B b;
g(b) ; // la g() richiama B::f()
D d;
g(d); //la g() richiama D::f()
}



Ovviamente considerando che la f() in B è definita virtual.

La domanda è : ma se nell'ultimo caso viene invocata D::f() può essere, anzi è probabile che essa operi sugli attributi di D che B non ha. Come fa il puntatore a referenziare correttamente quegli attributi ?

Forse sto sbagliando perché in realtà è solo la chiamata ad essere invocata il resto delle istruzioni di f() si svolgono proprio come se fossero state invocate da d.f(); è un mio pensiero ... chissà .. delucidami

cionci
25-05-2007, 21:46
Ogni volta che instanzi un oggetto di una classe derivata viene instanziato anche un oggetto della classe base....

leon84
25-05-2007, 21:47
Ogni volta che instanzi un oggetto di una classe derivata viene instanziato anche un oggetto della classe base....

Certo perché implicitamente viene invocato il costruttore della classe base. giusto ?

cionci
25-05-2007, 21:51
Giusto...

leon84
30-05-2007, 12:20
Scusate se riapro l'argomento ma io riesco ad effettuare la conversione anche utilizzando static_cast più che dynamic_cast. Mi spiegate ?

Non riesco a capire la differenza di : tempo di esecuzione e compilazione. Mi spiego :

Se ho :
B b;
D d;
B* pb = &b;
D* pd = static_cast<D*> (pb);

Se a pb assegno l'indirizzo di un tipo b per forza di cose nel cast successivo il compilatore (e quindi al tempo di compilazione sa che pb punta a un tipo b). In qualche circostanze non riesce a saperlo al tempo di compilazione ?

marco.r
31-05-2007, 09:22
Scusate se riapro l'argomento ma io riesco ad effettuare la conversione anche utilizzando static_cast più che dynamic_cast. Mi spiegate ?

Non riesco a capire la differenza di : tempo di esecuzione e compilazione. Mi spiego :

Se ho :
B b;
D d;
B* pb = &b;
D* pd = static_cast<D*> (pb);

Se a pb assegno l'indirizzo di un tipo b per forza di cose nel cast successivo il compilatore (e quindi al tempo di compilazione sa che pb punta a un tipo b). In qualche circostanze non riesce a saperlo al tempo di compilazione ?
Quando ad esempio passi il puntatore ad un'altra funzione:


void foo( B* b )
{
D* d = static_cast<D*>(b);
/* .... */
}

void boo()
{
B* b = new B();
B* b2= new D();
foo(b);
foo(b2);
}

In questo caso il compilatore non puo' sapere tutti i casi in cui usi la funzione foo, e quindi verificare durante la compilazione che venga sempre passato un tipo D