Reputation: 2999
I have a class 'A' that overrides the + operator, and a subclass 'B'.
I want to inherit 'A's + operator but instead of returning type A I want to return type B.
How can I go about doing this? I tried calling the parent's operator from B and casting the result to an A object but it won't let me cast a parent to a child
Can my + operator somehow return a generic 'A' pointer or something?
Upvotes: 4
Views: 404
Reputation: 66922
I frequently see it done in the following way:
class A {
int a;
A(int rhs) :a(rhs) {}
public:
A& operator+=(const A& rhs) {a+=rhs.a; return *this}
A operator+(const A& rhs) {return a+rhs.a;}
};
class B : public A {
int b;
public:
B(const B& rhs) :A(rhs), b(rhs.b) {}
// VVVVVVVVVVVVVVVVVV
B& operator+=(const B& rhs) {A::operator+=(rhs); b+=rhs.b; return *this;}
B operator+(const B& rhs) {return B(*this)+=rhs;}
};
Upvotes: 2
Reputation: 14619
It could - no technical reason it couldn't - it just violates some expectations when using operators. So if this is code for yourself, go for it, but if it's going to be read or used by other people, I'd reconsider for the following reasons:
+=
and *=
return a reference to the object they were called on after modifying that object. Operators like +
and *
return a new object (they pretty much have to, as the implication is that the object they're called on isn't changed). They don't return a pointer to a new object because:delete
an object they get back from an operator, which will cause memory leaks, and:MyClass a = b + c + d;
won't work, because the return type (MyClass*
) won't match the argument type you need to pass into the operator (probably const MyClass&
).Ultimately, just do whatever makes life easiest for whoever's going to be using the code - and if it's just you, you can do anything you want. Just be careful if it's going to fall into other people's hands, because they will make assumptions.
Hope this helps!
Edit: An example that returns a reference to a new object:
A& A::operator + (const A& other) const
{
A* temp = new A(); // <- This is why it's a potential memory leak
/* Do some stuff */
return *temp;
}
But, having had a little more time to think about this, I'd propose an alternative: Define an =
operator for B that takes an A as its argument. Then you could do things like this:
B b1;
B b2;
B b3 = b1 + b2;
And it wouldn't matter that b1 + b2
returned an A, because it was converted back to a B during the =
. If this works for you, I'd recommend it above any other method, as it lets all the operators have expected behaviours.
Upvotes: 2
Reputation: 96251
The simplest way to solve this problem is to implement operator+
in terms of operator+=
. So roughly:
A::operator+=(const A& right) { /* stuff */ }
B::operator+=(const B& right) { static_cast<A&>(*this) += right; /* stuff */ }
operator+(B left, const B& right) { return B += right; }
Upvotes: 1