Le funzioni di conversione sono la risposta a questo
Poiché il copyctor accetta sempre il proprio tipo come argomento, non c'è spazio per accettare un Drink
nel copy-ctor di Coffee
.
class Coffee: public Drink
{
...
public:
Coffee(const Coffee& other);
...
};
Se vuoi ancora inizializzare un caffè da un drink (possibilmente caffè), puoi utilizzare un operatore di conversione. Nota che vuoi decidere cosa fare se Drink
NON è un Coffee
. Ho inserito nel codice sotto un'eccezione in modo che se i dati di origine non sono un Drink
, non voglio procedere con la creazione di un oggetto Coffee
.
class Coffee: public Drink
{
...
public:
//Standard copy-ctor
Coffee(const Coffee& other);
//Conversion function
Coffee(const Drink& drink)
{
const Coffee& other = dynamic_cast<const Coffee&>(drink);
//this->x = other.x;
//this->y = other.y;
}
};
In questo modo, se il riferimento passato è di un tipo diverso (ad esempio Drink o Tea), viene generata un'eccezione std::bad_cast
e la creazione dell'oggetto viene interrotta.
.
.
.
//d1: drink reference pointing to object of type 'Drink' OR 'Tea' OR 'Coffee'
try
{
Coffee c1(d1);
cout << "Created coffee from drink" << endl;
}
catch(bad_cast& ex)
{
cout << "Exception : " << ex.what() << endl;
}
Il codice sopra funzionerà correttamente per Coffee
oggetto e genererà eccezioni per qualsiasi altro tipo.
Se desideri lavorare diversamente, puoi gestire l'eccezione nel ctor e andare da lì. Si noti che la gestione delle eccezioni nel ctor è generalmente disapprovata, a ragione.
NOTA CHE dynamic_cast funzionerà per le gerarchie polimorfiche, ad esempio con almeno 1 funzione virtuale nella classe base.
.
.
.