Qui è molto semplice gerarchia di classi:Dov'è necessario! = L'operatore deve essere definito in una gerarchia di classi?
class A
{
public:
A(int _a) : a(_a) {}
virtual bool operator==(const A& right) const
{
return a == right.a;
}
virtual bool operator!=(const A& right) const
{
return !(*this == right);
}
int a;
};
class B : public A
{
public:
B(int _a, int _b) : A(_a), b(_b) {}
virtual bool operator==(const B& right) const
{
return A::operator==(right) && b == right.b;
}
int b;
};
Come si può vedere, l'operatore = è definito nella classe base. Poiché sono molto pigro, non voglio duplicare un codice così semplice in tutte le classi derivate.
Unfortunatley, con questo codice:
A a4(4), a5(5), a4bis(4);
assert(a4 == a4bis);
assert(a4 != a5);
B b1(4,5), b2(4,6);
assert(!(b1 == b2));
assert(b1 != b2); // fails because B::operator== is not called!
b1 != b2
restituisce false, perché esegue A::operator!=
che chiama poi A::operator==
piuttosto che B::operator==
(anche se l'operatore è virtuale, come derivato parametro versione della classe è diversa, sono non collegato nel vtable).
Quindi qual è il modo migliore per indicare! = Operatore in modo generico per una gerarchia di classi?
Una soluzione è quella di ripetere in ogni classe, B
avrebbero allora:
virtual bool operator!=(const B& right) const
{
return !(*this == right);
}
ma questo è un dolore quando si hanno molte classi .... ho 30 ....
un'altra soluzione potrebbe essere quella di avere un approccio modello generico:
template <class T>
bool operator!=(const T& left, const T& right)
{
return !(left == right);
}
Ma questo bypassa qualsiasi !=
operatore definito da ogni classe .... quindi potrebbe essere rischioso se uno Decla rosso in modo diverso (o se uno ha dichiarato uno ==
stesso chiamando !=
, si finirebbe con un ciclo infinito ...). Quindi ritengo che questa soluzione sia molto pericolosa ... eccetto se possiamo limitare il template da utilizzare per tutte le classi derivate dalla classe di livello superiore della nostra gerarchia (A
nel mio esempio) .... ma non lo faccio pensa che sia fattibile.
Nota: non sto ancora utilizzando C++ 11 ... mi dispiace.
Inoltre, attualmente, 'A (42) == B (42, 0)' come si confronta solo la parte 'A' ... – Jarod42
Per chiarezza e per garantire che A continua a lavorare in modo indipendente (se non si indossa Lo voglio, non hai bisogno di ricavarne B), implementa! = per A, B, C, D e qualsiasi cosa tu abbia nella tua gerarchia. Ancora una volta se non ne hai bisogno, perché hai bisogno di derivare affatto? – Robinson