From this implementing operator== when using inheritance question, I see people say that operator==
should not be made virtual
(the accepted answer even says "operators cannot be virtual", which I found that is not true later):
c++ allows operators to be virtual. but i wouldn't make them virtual. polymorphism and operators actually don't fit together very well (and free operator functions obviously can't be virtual at all). ---- Johannes Schaub - litb
-1. Making Person::operator== virtual is not sufficient: Employee::operator== must be rewritten to have the same signature. Moreover, this would still lead to the issue pointed by Douglas, i.e. assymetry of the comparison operation, which is...weird. ---- Luc Touraille
I don't understand why I can't make operator==
virtual
. I wrote this code and seem to work well with polymorphism:
#include <iostream>
#include <typeinfo>
using namespace std;
struct Base {
int b1 = 1;
int b2 = 2;
virtual bool operator==(const Base& rhs) const {
cout << "Base" << endl;
if (typeid(*this) != typeid(rhs)) {
cout << "false" << endl;
return false;
}
else {
cout << "true" << endl;
return (b1 == rhs.b1) && (b2 == rhs.b2);
}
}
};
struct Derived : public Base {
int d1 = 3;
int d2 = 4;
virtual bool operator==(const Base& rhs) const override {
cout << "Derived" << endl;
if (typeid(*this) != typeid(rhs)) {
cout << "false" << endl;
return false;
}
else {
cout << "true" << endl;
const Derived& rrhs = static_cast<const Derived&>(rhs);
return (b1 == rrhs.b1) && (b2 == rrhs.b2) && (d1 == rrhs.d1)
&& (d2 == rrhs.d2);
}
}
};
int main()
{
Derived d;
Base b1, b2;
Base *bptr1, *bptr2, *bptr3;
bptr1 = &b1;
bptr2 = &d;
bptr3 = &b2;
if (*bptr2 == *bptr1) {
cout << "1" << endl;
}
else {
cout << "0" << endl;
}
if (*bptr3 == *bptr1) {
cout << "1" << endl;
}
else {
cout << "0" << endl;
}
if ((d == b1) != (b1 == d)) {
cout << "xxx";
}
return 0;
}
Is there any problem with my code?
typeid(*this) != typeid(rhs)
then you should take that as a sign you're doing something wrong. I would recommend that you create a non-member (but possiblyfriend
)operator==
function which then calls avirtual
comparison function, as infriend bool operator==(Base const& lhs, Base const& rhs) { return lhs.compare_equal(rhs); }
. Then overridecompare_equal
in child objects as needed, with downcasts of therhs
. – Kappenneif (*bptr2 == *bptr1) { cout << "1" << endl; } else { cout << "0" << endl; }
could be written more compact ascout << (*bptr2 == *bptr1) << endl;
(with the exact same outcome? – Skyjackbool operator=
orbool equals
or whatever. What is your application domain that requires equality comparison of this kind? – Heartthrobtypeid
with your approach right? The book uses a non-member friend function as you describe to implement this. It looks like this wandbox.org/permlink/O8m6j3l2z3rvQ3xs . What's the differences between this and mine? Which is better? – Smoothtongued