Sto esaminando alcuni codici legacy e mi sono imbattuto in un caso in cui lo sviluppatore ha "esteso" una classe esistente con membri aggiuntivi, utilizzando l'ereditarietà come sua arma preferita. Essenzialmente si riduce a qualcosa del genere:
struct A
{
int something_old;
};
struct B : public A
{
int something_new;
};
C'è una sezione di codice in cui hanno un'istanza di A, ma in realtà vogliono un'istanza di B. Ecco come sono riusciti a ottenerla:
auto aa = GetAn_A(); // for example
:
B bb;
*(A*)&bb = aa; // <-- code smell?
bb.something_new = 42;
Questo sembra funzionare bene: taglia bb e poi assegna alla parte affettata. Ma non posso fare a meno di pensare che in questi giorni illuminati del C ++, tutto ciò che l'hacking 'n' slicing con & 's e *' è un po 'vecchia scuola.
C'è un odore di codice qui e, se sì, quanto è grande un odore? Dovrebbe essere possibile scrivere così?
Se è smelly, dove l'autore ha iniziato a perdere la trama e cosa avrebbe dovuto / avrebbe dovuto fare per ottenere il risultato desiderato, cioè un'estensione a una classe esistente (tenendo conto di mente che A e B sono significativamente più complicati di questo in realtà, e che A è stato scritto qualche tempo prima di B)?