Implementing an operator in a child class

Hi all,

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)?

Cheers, TheBear
Last edited on
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 == ?
Hi Bazzy,

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?

Cheers TheBear

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#include <iostream>

class A
{
	public:
		int a;
		virtual bool operator==(const A& other)
		{
			std::cout << "== of A" << std::endl;
			std::cout << "Value of this->a: " << a << std::endl;
			std::cout << "Value of other.a: " << other.a << std::endl;
			return other.a == a;
		}
};

class B : public A
{
	public:
		int b;
		virtual bool operator==(const B& other)
		{
			std::cout << "== of B" << std::endl;
			std::cout << "Value of this->b: " << b << std::endl;
			std::cout << "Value of other.b: " << other.b << std::endl;
			return (other.b == b) && (CFoo::operator==(other));
		} 
};

int
main(int argc, char** args)
{
	A a1, a2;
	B b1, b2;

	a1.a = 15;
	a2.a = 15;
	std::cout << (a1 == a2) << std::endl << std::endl;
	a2.a = 16;
	std::cout << (a1 == a2) << std::endl << std::endl;

	b1.a = 1;
	b2.a = 1;
	b1.b = 12;
	b2.b = 12;
	std::cout << (b1 == b2) << std::endl << std::endl;
	b2.b = 13;
	std::cout << (b1 == b2) << std::endl << std::endl;
	b2.b = 12;
	b2.a = 2;
	std::cout << (b1 == b2) << std::endl << std::endl;

	A* a3 = &b1;
	std::cout << ((*a3) == b1) << std::endl << std::endl;
	return 0;
}


It appears that the keyword virtual has no effect on operator==

Notice that B == is not the same as A == :
1
2
bool operator==(const A& other)
bool operator==(const B& other)
Parameter types are different so B == will overload A ==, it won't override it
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.

Example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
class A
{
public:
    int a;
    bool operator==(const A& other) const
    {
        // make sure the types are the same
        if(typeid(*this) != typeid(other))
            return false;
            
        // if they are the same, then compare them
        return Compare(other);
    }
    
private:
    virtual bool Compare(const A& other) const
    {
        // compare A members
        return a == other.a;
    }
};

class B : public A
{
public:
    int b;
    // no == operator

private:
    virtual bool 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))
            return false;
            
        // 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;
    }
};
Last edited on
Hi again,

Bazzi: I should have seen that.

Disch: This really seems to be a good way to implement the desired behavior, thanks.
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.
Hi jsmith,

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:
    virtual bool compare(const A& other) const;
};
class B : public virtual A {/*...*/};
class C : public virtual 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 ‘virtual bool 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.

TheBear
Topic archived. No new replies allowed.