Mi sto perdendo, o meglio, mi sono gia' perso, nei confronti dei puntatori passati come parametro a un metodo e il loro "significato".
Ho creato una porzione di codice che dovrebbe simulare il mio problema.
Ho una serie di classi derivate da Abstract, Derived1 e Derived2.
Ho la necessita' di cambiare strada facendo la classe dell'oggetto istanziato, ho quindi creato una serie di classi derivate da AbstractConverter, che implementano un metodo convert che preso come parametro in input un puntatore a un oggetto di tipo Abstract, lo converte.
Ora, compilato a casa per il problema specifico, no problem, ma si pianta runtime quando arrivato al metodo convert deve creare l'istanza del nuovo oggetto, dando un messaggio di errore del tipo che il costruttore richiamato e' di tipo virtuale... (vado a memoria, mi pare di ricordare che ieri sera mi desse un messaggio con questo significato).
Il codice che ho postato sotto, che riproduce lo schema con cui ho strutturato il caso, compilato e fatto girare su questo sito http://cpp.sh/ va senza problemi.
Dove sta il problema?
Il dubbio che mi e' venuto e' che io passo il puntatore al metodo convert per valore, quindi le operazioni che faccio all'interno del metodo convert in realta' non mi stanno modificando l'oggetto che vorrei modificare, quindi in realta' dovrei passare il puntatore per riferimento, in modo da agire sull'oggetto che voglio modificare.
Nel caso sotto rirpodotto probabilmente tutto fila liscio in quanto non devo convertire anche i dati membro dell'oggetto, mentre nel mio caso reale la conversione di classe e' dovuta a una "conversione di dati" da un sistema ad un altro.
Ecco il codice che simula lo schema di implementazione da me utilizzato:
codice:
#include <iostream>
#include <string>
class Abstract
{
public:
enum Type: unsigned int {Derived1,Derived2};
virtual ~Abstract(){};
virtual void hello()=0;
virtual Abstract::Type getType()=0;
};
class Derived1: public Abstract
{
virtual void hello()
{
std::cout<<"\nHello from Derived1";
};
virtual Abstract::Type getType()
{
return Abstract::Derived1;
};
};
class Derived2: public Abstract
{
virtual void hello()
{
std::cout<<"\nHello from Derived2";
};
virtual Abstract::Type getType()
{
return Abstract::Derived2;
};
};
class AbstractConverter
{
public:
enum Convert: unsigned int{ToDerived1,ToDerived2};
virtual ~AbstractConverter(){};
virtual void convert(Abstract* object_to_convert)=0;
};
class ConverterToDerived1: public AbstractConverter
{
public:
virtual void convert(Abstract* object_to_convert)
{
switch(object_to_convert->getType())
{
case Abstract::Derived1:
std::cout<<"\nE' gia' Derived1";
break;
case Abstract::Derived2:
fromDerived2(object_to_convert);
break;
}
};
private:
void fromDerived2(Abstract* object_to_convert)
{
delete(object_to_convert);
object_to_convert=new Derived1();
}
};
class ConverterToDerived2: public AbstractConverter
{
public:
virtual void convert(Abstract* object_to_convert)
{
switch(object_to_convert->getType())
{
case Abstract::Derived1:
fromDerived1(object_to_convert);
break;
case Abstract::Derived2:
std::cout<<"\nE' gia' Derived2";
break;
}
};
private:
void fromDerived1(Abstract* object_to_convert)
{
delete(object_to_convert);
object_to_convert=new Derived2();
}
};
int main()
{
Abstract* abstract=0;
//prova del costruttore di Derived1
abstract= new Derived1();
std::cout<<"\nAbstract e' di tipo "<<abstract->getType();
abstract->hello();
delete(abstract);
//prova del costruttore di Derived2
abstract= new Derived2();
std::cout<<"\nAbstract e' di tipo "<<abstract->getType();
abstract->hello();
AbstractConverter* converter=0;
//ora provo il converter to Derived1
converter= new ConverterToDerived1();
//abstract ora è Derived2, tento la conversione a Derived1
converter->convert(abstract);
std::cout<<"\nAbstract e' di tipo "<<abstract->getType();
abstract->hello();
//abstract ora è Derived1, tento la conversione a Derived1
converter->convert(abstract);
std::cout<<"\nAbstract e' di tipo "<<abstract->getType();
abstract->hello();
delete(converter);
//ora provo il converter to Derived2
converter= new ConverterToDerived2();
//abstract ora è Derived1, tento la conversione a Derived2
converter->convert(abstract);
std::cout<<"\nAbstract e' di tipo "<<abstract->getType();
abstract->hello();
//abstract ora è Derived2, tento la conversione a Derived2
converter->convert(abstract);
std::cout<<"\nAbstract e' di tipo "<<abstract->getType();
abstract->hello();
return 0;
}