Supponiamo che io ho la seguente gerarchia di classe:Qual è il modo giusto per sovraccaricare l'operatore == per una gerarchia di classi?
class A
{
int foo;
virtual ~A() = 0;
};
A::~A() {}
class B : public A
{
int bar;
};
class C : public A
{
int baz;
};
Qual è il modo giusto per sovraccaricare operator==
per queste classi? Se faccio loro tutte le funzioni libere, allora B e C non possono sfruttare la versione di A senza casting. Sarebbe anche impedire a qualcuno di fare un confronto profondo avendo solo riferimenti a R. Se li faccio funzioni membro virtuali, poi una versione derivata potrebbe assomigliare a questo:
bool B::operator==(const A& rhs) const
{
const B* ptr = dynamic_cast<const B*>(&rhs);
if (ptr != 0) {
return (bar == ptr->bar) && (A::operator==(*this, rhs));
}
else {
return false;
}
}
Ancora una volta, devo ancora lanciare (e si sente sbagliato). C'è un modo preferito per farlo?
Aggiornamento:
Ci sono solo due risposte finora, ma sembra che la strada giusta è analogo a l'operatore di assegnazione:
- Fai classi non foglia astratti
- protette non virtuale nelle classi non foglia
- Pubblico non virtuale nelle classi foglia
Qualsiasi tentativo dell'utente di confrontare due oggetti di tipi diversi non verrà compilato perché la funzione di base è protetta e le classi foglia possono sfruttare la versione del genitore per confrontare quella parte di dati.
Questo è un doppio problema classico spedizione. O la tua gerarchia è conosciuta in anticipo, nel qual caso devi scrivere n * (n - 1)/2 funzioni, oppure no e devi trovare un altro modo (es. Restituire un hash dell'oggetto e confrontare gli hash). –