Ho sempre sentito che non si dovrebbe ereditare da una classe senza distruttori virtuali e non ho prestato molta attenzione perché non uso l'ereditarietà tutto questo spesso. Questa regola si applica anche se non si desidera utilizzare il polimorfismo, ma si desidera semplicemente tutte le funzionalità di una classe e si desidera aggiungerne altre? Per essere concreti, la classe seguente sarebbe sicura, con un comportamento ben definito, a patto che non la usassi polimorficamente? (vale a dire senza puntatori Eliminazione di base a oggetti derivati)Eredita da classi senza distruttori virtuali
template<typename T>
class SomewhatSafeVector : public std::vector<T>
{
public:
typedef std::vector<T> base;
T& operator[](unsigned n) {
if (n >= base::size())
{
throw IndexOutOfBounds();
}
return base::operator[](n);
}
};
Non importa se è OK o no, ma non si dovrebbe ancora derivare da contenitori di libreria standard. Inoltre, se hai problemi ad accedere a contenitori dinamici all'interno dei loro limiti, potresti preferire guardare il tuo pensiero algoritmico di grandi dimensioni (pensa "0-1-molti" e "intervalli"), dal momento che un accesso non vincolato è di solito un errore * logico *. –
Penso che nel tuo particolare esempio, l'ereditarietà non è una soluzione terribilmente elegante poiché l'ereditarietà è destinata al riutilizzo delle interfacce, non al riutilizzo dell'implementazione. È chiaro che non riutilizzate l'interfaccia, dato che il vostro operatore '[] 'genera un'eccezione che non' std :: vector'. Se si desidera riutilizzare il codice, basta usare semplici funzioni condivise o (come in questo caso), rendere 'std :: vector' un membro di' SomewhatSafeVector'. –
@KerrekSB: Al primo, perché no? Per il secondo, non ho problemi. Ma penso che i contenitori controllati dai limiti sarebbero una buona idea per scopi didattici e di debug. –