Ho trovato questo stesso codice qui: link
struct Base { virtual Base& operator+=(int) = 0; };
struct X : Base
{
X(int n) : n_(n) { }
X& operator+=(int n) { n_ += n; return *this; }
int n_;
};
struct Y : Base
{
Y(double n) : n_(n) { }
Y& operator+=(int n) { n_ += n; return *this; }
double n_;
};
void f(Base& x) { x += 2; } // run-time polymorphic dispatch
Ho letto molti Q & Riguardo a quando (e quando no) usare un distruttore virtuale, ma sono perplesso da questo codice di esempio. La mia comprensione da manuale del C ++ dice: "Aha! Una classe base senza un distruttore virtuale è cattiva . Può verificarsi una perdita di memoria o un comportamento indefinito." Penso anche che questo stile appaia nella libreria standard del C ++, ma non conosco un esempio in cima alla mia testa.
Che cosa accade se uso X
(e Y
) come tale ...?
X* x = new X(5);
// Scenario 1
delete x; // undefined behaviour...? Does default dtor for 'Base' get called?
// Scenario 2
Base* b = x;
delete x; // undefined behaviour...?
Forse sono confuso riguardo a (a) usare una classe in modo sicuro senza un distruttore virtuale contro (b) sicurezza per progetto / Non riesco a sbagliarmi.
Nel caso (a), per usare in modo sicuro, allocare solo lo stack. Ciò richiede disciplina!
Nel caso (b), aggiungere un distruttore virtuale in Base
o forzare l'allocazione dello stack tramite un costruttore privato e un metodo factory statico pubblico. Questo non richiede disciplina. (Sebbene questo commento di David Rodríguez confuso me di più! "Perché dovresti farlo [prevenire l'allocazione dell'heap]?")