开发者

c++ overloaded method in derived class

开发者 https://www.devze.com 2022-12-17 18:20 出处:网络
I have the following question: Assume base class A with method: A& operator+(A& a) {...} I also have a derived class B which overloads (or at least it should so) this method:

I have the following question:

Assume base class A with method:

A& operator+(A& a) {...}

I also have a derived class B which overloads (or at least it should so) this method:

A& operator+(B& b) {...}

The problem is that if i want to call something like: b + a (where b is of type B and a of type A) i get a compile error. (error C2679: binary '+' : no operator found which takes a right-hand operand of type 'A' (or there is no acceptable conversion)).

Shouldnt that call the base class method? (it looks like it overrides the method..) If not, why? Is there a way to fix this (dont tell me to overload the method in B with A&)

Sorry i dont give examples in formated text, but i dont know how to format it.

Thanks in advance!

PS Im usi开发者_如何学JAVAng Visual studio 2010 beta.


No, it won't call the base class function. Class B has an operator+, it doesn't take the correct parameter, end of story.

You can define operator+ as a free function, not in any class. Perhaps a friend, if it needs to access private data:

A operator+(const A &lhs, const A &rhs) { ... }
B operator+(const B &lhs, const B &rhs) { ... }

Then b + a will call the first operator, as will a + b. b + b will call the second.

Alternatively, you could "un-hide" the base class implementation, by putting this in class B:

using A::operator+;

it's probably best not to, though. Most operators work better as free functions, because then you get automatic conversions on both operands. C++ never performs conversions on the LHS of a member function call.

Btw, operator+ almost certainly should return by value, not by reference, since an automatic (stack) variable no longer exists once the function returns. So the caller needs to be passed a copy of the result, not a reference to it. For this reason operator+ and inheritance aren't a great mix, although it can probably work as long as the caller knows what they're doing.


The problem is called hiding - a member function in a derived class hides functions with the same name in the base class. In this case you can't access A::operator+(A&) because it's being hidden by B::operator+. The way to fix this is to define B::operator+(A&), and possibly have it call the base class function.

Edit: There's a section in the C++ FAQ Lite that goes into more detail about this problem and offers another possible solution, namely the using keyword.


The problem is that you are defining the member operator, so when called as b + a it results in b.operator+( a ), which doesn't exist.

Accepted practice is to define free operators that themselves would call [virtual] members on the arguments.

Edit:

Standard example of what I'm talking about is adapting a class hierarchy for output streaming:

class base
{
public:

  virtual ~base();
  virtual void print( std::ostream& ) const;
};

std::ostream& operator<<( std::ostream& out, const base& b )
{
  b.print( out ); return out;
}

This doesn't really work for math operations since you want to return by [const] value, not reference, i.e. avoid nonsense like a + b = c;.

For example, addition of real and complex numbers is defined, but yields complex number as the result, so you cannot derive complex from real. The other way - maybe. But still you want to define exact operations interface:

const real operator+( const real&, const real& );
const complex operator+( const complex&, const complex& );

Hope this gives you enough to re-think your design :)


Couple of things come to mind. First, you would generally want to make the operator + "virtual". Then, the derived operator + taking a reference to B would be an override due to co-variance, instead of hiding the base class implementation, which is what is happening here.

That said, I suspect (but can't say for certain without compiling a test project) that that would actually solve your problem. That's because the standard answer for binary operators is to use static methods that take two parameters on the class. The C++ STL uses this technique extensively, and I don't know of a reason to attempt to implement binary operators as instance methods, virtual or not. It's just too confusing, with no real up-side.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号