Newsgroup: it.comp.lang.c++
Titolo: polimorfismo

class Tree
{
Node* root;
virtual Node* create_node() const {return new Node();}
Tree() {root = create_node();}
};
class SFTree: public Tree
{
virtual Node* create_node() const {return new SNode();}
SFTree(): Tree() {}
};
SFTree tree;
Mi esegue create_node di Tree e non di SFTree!
Perchč?
Ma se l'ho riscritto in SFTree?!
Come faccio in c++ invece a ottenere la chiamata voluta?

 Come faccio in c++ invece a ottenere la chiamata voluta?
Posso risponderti con un esempio (assolutamente non esaustivo...)
che spero ti chiarisca un po' le cose?
SiMoStro
************************
#include <iostream>
using namespace std;
class Base {
protected:
        int i;
public:
        Base(){};
        virtual void init(int _i){i=(_i+1);}
        void print(){cout<<"i = "<<i<<endl;}
};
class Derivata: public Base {
public:
        Derivata(){};
        virtual void init(int _i){i=_i;}
};
int main(){
Base* pb1, *pb2;
pb1=new Derivata;
pb2=new Base;
pb1->init(3);
pb2->init(3);
pb1->print();
pb2->print();
return 0;
}
***************


 ok queste cose le dovrei avere chiare.Quindi in c++ nel costruttore viene
sempre eseguiti i metodi della classe a cui appartiene, e non c'č modo di
usare il polimorfismo ?

 usare il polimorfismo ?
Parrebbe proprio di no, quantomeno non nel modo che intendi tu;
per altro, se i costruttori non possono essere dichiarati virtual un
motivo ci sarà.
Il tipo di inizializzazione che vuoi fare tu è preferibile spostarlo
in un altra funzione (effettivamente virtual, da chiamere "dopo" la
creazione di un oggetto e cioè su un oggetto esistente);
sarebbe buona norma mantenere i costruttori il più semplice possibile;
il dynamic binding richiesto per le chiamate alle funzioni
virtuali sposta "il più tardi possibile" la dereferenziazione
alle funzioni, in fase di "costruzione", praticamente, un oggetto
ancora non esiste, probabilmente è per questo che non si riesce a fare
quello che vorresti.
Una sorta di "soluzione" a ciò che vuoi fare tu, forse, la puoi
trovare qui:
http://www.parashift.com/c++-faq-lite/virtual-functions.html
Il mio consiglio, quando si richiede polimorfismo, è prima costruisci,
poi inizializzi.
Ciao!
SiMoStro

...

Perche' nell'ambito del costruttore della classe base eventuali
ridefinizioni di funzioni membro virtuali presenti in classi derivate
non sono ancora disponibili. Questo impedisce di chiamare funzioni che
potrebbero operare su membri dato non ancora inizializzate.
Sospetto che l'eredita' non sia il meccanismo migliore per
generalizzare quello che cerchi di fare. Se vuoi implementare un
albero generico faresti meglio ad usare un template.
Ciao,
Nicola

 albero generico faresti meglio ad usare un template.
Può essere!
Quello che voglio fare vorrebbe essere una serie di alberi estesi, in cui in
alcune derivazioni devo utilizzare nodi derivati.
Potrei usare i template, però non vorrei lasciare al programmatore la
possibilità di usare un nodo di tipo non adeguato in un albero derivato.
Ad esempio se il nodo NodeExt3 non è quello giusto per l'albero TreeExt2,
vorrei che questo non fosse permesso:
TreeExt2<NodeExt3> t;
Inoltre non essendo abituato a lavorare con i template temo di fare un
casino, soprattutto con la struttura del codice! ;-)
Cmq ora ci provo.

 TreeExt2<NodeExt3> t;
http://www.boost.org/libs/concept_check/concept_check.htm
-- 
sbi