Newsgroup: it.comp.lang.c++
Titolo: OOP & C++ connubio contrastato!!

Eccellentissimi guru della OOP
Sono uno studente universitario e per un esame sto incominciando a masticare
un pò di OOP & C++, ho però i seguenti dubbi:
(preciso che uso il Borland C++ 3.0):
----------------------------------------------------------------------------
----
(1) MEMORIA DINAMICA O STATICA?
Supponiamo di avere allocato in maniera dinamica uno stack tramite:
Class Stack {       // Classe Stack
private:
int top, *v;
public:
void Push (int n);
Stack (int n) {top=-1;v=new int [n];};
~Stack () {delete v;};
};
void main (){   // Contesto Principale
 {
 Stack *ps = new Stack (100);
ps->Push(666);
 };
};
L'intero top è allocato nell'heap di sistema in conseguenza del fatto che
tutto lo stack è allocato dinamicamente ?
Oppure top è allocato nello stack di sistema poichè è una variabile statica
(cioè non allocata con new) ?
----------------------------------------------------------------------------
----
(1.1) DEALLOCATO O NO ?
Riguardo alla domanda al punto (1), come deallocare il top dello Stack ?
Se top è allocato nell'heap dovrei poter usare ~Stack () {delete v;delete
top;}; ma il compilatore non me lo accetta dicendomi che la delete non può
cancellare un puntatore a costante.
Se invece top è allocato nello stack, top muore non appena si esce fuori
dalla zona di influenza dell'istanza dello stack oppure è ancora vivo e
vegeto fino alla conclusione del main?
----------------------------------------------------------------------------
----
(1.2) DISTRUTTO O NO ?
Sempre riguardo alla domanda al punto (1), mi è stato detto che dopo aver
fatto la Push nel main, il distruttore non viene
richiamato automaticamente ma bisogna fare esplicitamente delete ps il che
comporta il richiamo del distruttore e la deallocazione
del vettore v.
E' vero?
Se si, perchè si istanziato dinamicamente lo stack?
E se è vero,a seguito del contesto {Stack P(67); P.Push (54);}; viene
richiamato automaticamente il distruttore?
----------------------------------------------------------------------------
----
(2) I DISTRUTTORI : ESSERE O NON ESSERE VIRTUALI ?
Dato un albero di generalizzazione, per fare in modo che i distruttori siano
chiamati in modo inverso rispetto alle chiamate dei costruttori (quindi
dalle sottoclassi alle superclassi) li si deve dichiarati virtual ?
Io ho provato senza e funziona tutto bene come mostra il seguente codice:
 #include <iostream.h>
class A {
public:
A(){cout<<"Sono il costruttore di A \n";};
~A(){cout<<"Sono il distruttore di A \n";};
};
#include <iostream.h>
class B:private A {
public:
B(){cout<<"Sono il costruttore di B \n";};
~B(){cout<<"Sono il distruttore di B \n";};
};
#include <iostream.h>
class C:public B {
public:
C(){cout<<"Sono il costruttore di C \n";};
~C(){cout<<"Sono il distruttore di C \n";};
};
#include <conio.h>
void main(){
clrscr();
C ic;
};
L'output è il seguente:
Sono il costruttore di A
Sono il costruttore di B
Sono il costruttore di C
Sono il distruttore di C
Sono il distruttore di B
Sono il distruttore di A
E' una necessità dipendente dal compilatore?
Questo è tutto!
Grazie anticipatamente per l'aiuto che vorrete darmi.

 E' una necessità dipendente dal compilatore?
No, dipende invece solo dal tuo codice.  Nel tuo esempio non vi e`
alcun delete, men che meno su puntatore a classe-base, quindi benche`
innocui i dtor virtuali non sono obbligatori.
Alex

 


 C ic;
In questo modo non hai polimorfismo. Prova così
A *ic = new C;
delete ic;
e vedrai che funziona come ti aspetti solo se poni virtual il
distruttore della classe A.
EMG

 innocui i dtor virtuali non sono obbligatori.
Se inutili non sono innocui in quanto costringono comunque il
compilatore a generare la vtable e questo mi sembra sia l'unico motivo
per cui non sono virtuali per default.
EMG

E' una necessità dipendente dal compilatore?
No, sono le regole del linguaggio ed una conseguenza del
type checking statico.
Paolo
--------------------------------------------------
  Paolo Marotta
  Computer Science, University of Pisa
  home:   
http://www.cli.di.unipi.it/~marotta
--------------------------------------------------


Si, ti sara` sfuggito, ma nel nuovo contesto P e` allocata
staticamente e quindi soggetta alle regole di scoping


 wrote in message
news:39313A80...@flashnet.it...

Innocui come semantica, effettivamente non come overhead in
quanto, se gia` l'oggetto non era polimorfico, lo rendono
comunque tale.  Il costo e` trascurabile se l'oggetto deve
essere polimorfico comunque (se la vtable/vptr comunque ci
sono, non e` che una entry in + costi...) salvo casi molto
particolari in cui si deve controllare il layout della vtable
stessa (per compatibilita` con standard o formati binari che
siano imposti dall'esterno; esigenza assai particolare, in
pratica vengono in mente solo standard come COM o SOM...).
Alex

 staticamente e quindi soggetta alle regole di scoping
Oops! Comunque è allocata automaticamente, non staticamente. O prendo un
altro abbaglio?
EMG

pratica vengono in mente solo standard come COM o SOM...).
Cos'e' SOM ?
--
Andrea Laforgia (
andrea_...@bigfoot.com
)
-----------------------------------------------------
"There is nothing better for understanding a kangaroo
 than seeing it jump." [D.Grune, C.J.H. Jacobs]

 Cos'e' SOM ?
System Object Model, un set di specifiche binarie per la
programmazione per componenti che l'IBM sudo` sangue per
promulgare negli anni '90 (senza molto successo, d'altra
parte; mi pare che solo OS/2 e AIX implementassero in parte
queste specifiche).  Uno schema molto ambizioso, ricco,
e complesso, rispetto alla semplicita` francescana (a
questo livello, cioe` quello delle specifiche binarie)
del COM, con gli usuali trade-off.  E come al solito, e`
il protocollo piu` semplice/elementare che si e` imposto.
Alex

System Object Model, un set di specifiche binarie per la
Grazie ;)


altro abbaglio?
Giusto... anche se in effetti avevo utilizzato il termine "staticamente"
in contrapposizione a "dinamicamente".


 sono, non e` che una entry in + costi...)
ma si passa comunque dalla vtable? Cioè, se l'oggetto non è polimorfico, il
distruttore virtuale lo rende tale, ma le chiamate a funzioni non virtuali
vengono comunque effettuate senza passare dalla vtable, giusto? Allo stesso
modo se l'oggetto era già polimorfico, ma il distruttore non viene dichiarato
virtuale, non si passa dalla vtable e quindi rendendolo inutilmente virtuale
si aggiunge anche l'overhead del deferenziamento. Certo è raro che un oggetto
polimorfico non necessiti di un distruttore virtuale, ma era solo per
chiarimi le idee :-)
Ciao FBF.

 chiarimi le idee :-)
Un oggetto polimorfico non richiede un distruttore virtuale se
e solo se non viene mai distrutto attraverso un puntatore a
classe-base.
In questo caso di "se e solo se" non vi e` nessun "overhead di
dereferenziamento"; il polimorfismo entra comunque in gioco
solo per chiamate attraverso puntatori (o reference).
Alex

 Alex
Grazie per il chiarimento.
Ciao FBF.

chiarimi le idee :-)
Molto raro, comunque quando un oggetto ha metodi virtuali, e` bene
che anche il distruttore sia virtuale.


 (ad esempio quando si usa la notazione del punto), ovviamente non
Non e` questione di notazione; se f() e` un metodo virtuale,
x.f(), in assoluta identita` di notazione, sara` polimorfica
("passera` dalla vtable", nella comune implementazione) se
x e` una reference, ma non se x e` un valore (oggetto).
Alex

 Non e` questione di notazione; se f() e` un metodo virtuale,
E due... manca la terza eresia e sono a posto! :(
Paolo
-- 
------------------------------------------------
  Paolo Marotta
  Computer Science, University of Pisa
 
http://www.cli.di.unipi.it/~marotta
------------------------------------------------