First of all: I hope this is the right forum for this sort of question. If not, feel free to move it.
i'm having to classes (say: CFoo and CBar), where CFoo is a superclass of CBar. Assume the operator "==" is overloaded in CFoo, and i want to overload in CBar, too.
The Question is: How do i call the "==" operator of CFoo in the "==" operator implementation of CBar?
One might consider calling ((CFoo*)this)->operator==(other);,
but this solution has a major drawback: the == operator of CFoo has to be not virtual. Also this is a rather ugly piece of code.
Has anyone a hint to do this better, in the best case without even knowing the names of the superclass(es) (like calling super.methodname() in Java)?
I assume with superclass you mean base class.
You can try with CFoo::operator == ( other )
BTW is == defined inside CFoo or is it an external function?
Do you need CBar's == the same as CFoo's == ?
thanks for the answer. CFoo::operator== works fine, and is acceptable regarding readability.
The operator is defined as a member of CFoo. The == operator of CBar should do the following:
Two CBars are equal iff they are equal as CFoos and the additional data defined in CBar is equal.
I also rechecked my claim that the solution from above works only if CFoo::operator== is not virtual; it is not true. It appears that the keyword virtual has no effect on operator==, as the appended example shows (check the last 2 lines of main, B::operator== is not called. Compiler was g++ 4.4.1 (ubuntu).). Any recommendations how to achieve polymorphism in this case?
This is actually somewhat of an interesting problem.
My approach would be to just have A ==. Don't make it virtual and don't put it in derived classes. Instead, have A == call a private virtual "Compare" function which compares child types, but only if the types are the same.
The derived B::Compare would need to downcast to the appropriate type.
class A
{
public:
int a;
booloperator==(const A& other) const
{
// make sure the types are the same
if(typeid(*this) != typeid(other))
returnfalse;
// if they are the same, then compare them
return Compare(other);
}
private:
virtualbool Compare(const A& other) const
{
// compare A members
return a == other.a;
}
};
class B : public A
{
public:
int b;
// no == operator
private:
virtualbool Compare(const A& other) const // note it takes an A parameter
{
// compare A members (and any other parents if multiple parents)
if(!A::Compare(other))
returnfalse;
// compare B members
// safe to static cast because A::== already confirmed the type
const B& otherb = static_cast<const B&>(other);
return b == otherb.b;
}
};
Yes, inheritance and operators don't mix too well.
Although the above works, the two "issues" with are that I cannot compare two B instances in the
same way as two A instances (can't compare B's at all; can use operator== on As), and that
in general it is not terribly maintainable.
what do you mean? Comparison of 2 Bs works very well, and it works as expected: simply use the operator ==. Actually, when you have a common base class for all classes in your hierarchy (like Object in Java), you can compare any pair of objects from this hierarchy.
I also consider this solution to be somewhat maintainable (though this could be better), as in every class, there is only class specific code to be implemented (within the compare-method).
There is only one thing i could not solve: It appears, when the class hierarchy has a dreaded diamond in it, i.e. the following situation appears:
1 2 3 4 5 6 7 8 9 10 11
class A
{
public:
operator==(const A& other);
//...
protected:
virtualbool compare(const A& other) const;
};
class B : publicvirtual A {/*...*/};
class C : publicvirtual A {/*...*/};
class D : public B, public C {/*...*/};
When I try to implement this in this way, i get some errors like the following (gcc 4.4.1, ubuntu version):
1 2
FooBar.cpp: In member function ‘virtualbool C::compare(const A&) const’:
FooBar.cpp:58: error: cannot convert from base ‘A’ to derived type ‘C’ via virtual base ‘A’
However, this seems more to be an error/misunderstanding of multiple inheritance to me, since i have not gotten very involved in that ever before. Also, its likely to not appear in my case.