Newsgroup: it.comp.lang.c++
Titolo: due o tre domande variate...

Ciao a tutti,
premetto che sono veramente ammirato del lavoro che tutti insieme (e
alcuni, ma non e' bello fare nomi, di piu') state facendo su questo
newsgroup. Quando mi sentiro' abbastanza ferrato comincero' a scrivere
anche io!
Dunque,
1) le variabili globali vengono costruite con in costruttore di default
se dichiarate. Es:
class A
{
int m;
public:
A() : m(4) {}
} a;
dichiara la classe A e costruisce un a di A con il default costruttore.
Ora:
Qual'e' il default costruttore dei tipi built-in?
Se in una classe (per esempio A scritta sopra) non inizializzo m
esplicitamente nel costruttore, il valore di m resta indefinito? 
Ed e' differente il comportamento di una variabile di tipo A se
automatica o globale, per quel che riguarda m? 
2) Supponendo di fare:
char* a = new char[10];
il compilatore mi alloca un area di memoria bastante a 10 caratteri e mi
mette in a il puntatore a codesta area di memoria.
Quando faccio: 
delete[] a;
libero l'area di memoria.
Se ora facciamo
class MyClass; 
MyClass* a = new char[10];
il compilatore alloca abbastanza memoria per contenere 10 oggetti di
tipo MyClass e li inizializza con il costruttore di default. 
Se ora faccio 
delete[] a;
viene chiamato il distruttore per ogni oggetto di tipo MyClass?
E se invece di un array di MyClass ho un array di puntatori a MyClass
cosa succede quando faccio delete[]? 
E se e' un array automatica?
Insomma, non ho le idee chiarissime su quando viene chiamato
automaticamente il distruttore e il costruttore
3) Nelle container class dell STL, quando metto un oggetto con push()
chiedo a vector di copiarlo in una sua memoria locale? E se voglio
evitare di copiarlo, o se l'operatore copia e' dichiarato nella sezione
private:, cosa succede? 
e se passo un puntatore, copia il valore del puntatore?
4) last question:
C'e' qualcuno che puo' spiegarmi a cosa serve la derivazione privata o
protetta. Nota bene: non cosa significa, ma in quale idioma o pattern la
si usa di solito. Equivalentemente, la sezione protected di una classe a
che serve?
Beh, e' tutto. 
Grazie per l'attenzione,
				Guido Gagliardi

 che serve?
I membri-dati protetti servono a far casino.  Stroustrup
ha dichiarato che se potesse tornare indietro e fare UN
cambiamento fra tutte le decisioni di progetto che prese
nel corso della lunga storia del C++, sarebbe quello di
non introdurli.  Non li usare (e men che meno quelli
pubblici, ovviamente).
Le funzioni protette servono a permettere un coupling
maggiore delle classi derivate, rispetto a quello che e`
permesso al codice cliente.  Puo` essere una scelta di
progetto tutto sommato ragionevole, visto che l'eredita`
di implementazione impone comunque un coupling tale
che, in pratica, ha senso solo "entro un singolo
componente" (cfr Lakos, "Large Scale" ecc).
Ad esempio, la design pattern mixin puo`
venire raffinata...:
    class StampabileConTimeout1:
        virtual protected Stampabile {
    public:
        virtual bool StampaConTimeout(time_t to) {
            // come sopra
        }
    };
    class deriv: public StampabileConTimeout1,
        private ImplementaStampabile {
    public:
        using Stampabile::IniziaStampa;
    };
Qui, la deriv non e` tenuta ad esporre al codice
cliente tutti i metodi di "Stampabile", puo` invece
farlo selettivamente con le "using".  Questo e`
grazie all'eredita` protected usata dalla
StampabileConTimeout1.
Qui, visto che l'eredita` protected e` quella di
una classe-interfaccia pura, essa equivale in
pratica a dichiarare protected dei _metodi_ (e
quindi non si applica quanto sopra sui problemi
dell'eredita` di implementazione) mantenendo
i vantaggi (di comodita` e prestazioni) della
override permessa dalla "dominance rule",
rispetto alla delegazione (piu` "pulita" e piu`
flessibile, meno comoda, un minimino meno
veloce).
Alex


Sei sicuro di questo? Ed è garantito dallo standard?


Da quanto detto prima, risulta che i built in possono essere considerati
esattamente come gli altri oggetti, con costruttore di default vuoto (e non
ridefinibile), quindi se m non ha static duration sara' indefinito,
altrimeti no (=0).
Saluti, Alberto.

]

 build-it) e' vuoto.
Non mi pare che sia corretta quest'ultima concettualizzazione.  Infatti,
ad esempio:
    template<class T>
    T defaulter()
    {
        return T();
    }
defaulter<int>() *deve* tornare 0, secondo lo standard C++; non e`
ammesso che torni altri valori.  In generale, un esplicito "int()" torna
pure zero, sempre secondo lo standard.  Qui chiaramente la static
initialization non c'entra, e allora, come concettualizzarlo se non
parlando di qualcosa come "pseudo-default ctor", che a te non pare
corretto?
Un default ctor, non vuoto ma "azzerante", c'e`, perche` se viene
invocato esplicitamente ne vediamo gli effetti.
Pero` non c'e`, perche` se NON viene invocato esplicitamente, ad
es. su variabili auto, restano piene di spazzatura, non azzerate (non
necessariamente, cioe`; ovvio che un dato compilatore e` libero
anche di azzerarle, se vuole, ma il programma non puo` farci
conto).
E allora, dire che "c'e`, ma e` uno *pseudo*-default" non mi sembra 
scorretto.  Strano "default" quello che funziona solo se _esplicito_ --
direi che "pseudo" e` un aggettivo ragionevole per esso:-)
Alex

 Sei sicuro di questo? Ed è garantito dallo standard?
Si`, cfr. nello standard i punti 3.6.2, 3.7.1, 8.5, ...
Alex

 pure zero, sempre secondo lo standard.
Questo proprio non lo sapevo. Pensavo che "int()" ritornasse un valore
indefinito.
Allora lo pseudo default constructor esiste!
Ho cercato nello standard ma non lo ho trovato. Dove lo trovo (io ho la
versione 1998-09-01) ?
Saluti, Alberto.

 versione 1998-09-01) ?
8.5, sub 5, dice, in parte: "To _default-initialize_ an object of type T
means [snip] the storage for the object is zero-initialized"; e sub 7,
"an object whose initializer is an empty set of parentheses, i.e. (),
shall be default-initialized".
Da questo consegue che "int()" torna un intero (tecnicamente un
temporary) che e` default-initialized, cioe`, causa 8.5 sub 5, con
"storage ... zero-initialized".
A norma delle regole non e` "proprio" un costruttore, non e`
"proprio" di default, ma, se non e` zuppa... e` "pseudo", dico io:-).
Mi rendo conto che le conseguenze di 8.5 sub 5 e 7 presi assieme
non sono immediatamente evidenti (a dir poco:-).  Puo` anche
darsi che qualche altro brano dello standard sia piu` chiaro in
merito, magari (osiamo sperarlo?-) persino con un esempio:-).
Comunque, chiedere su comp.std.c++ resta il modo migliore
di verificare:-).
Alex