Alex Rivera | Logout

Overload operators as member function or non-member (friend) function?

Asked 2009-12-15T06:00:45.377
12

I am currently creating a utility class that will have overloaded operators in it. What are the pros and cons of either making them member or non-member (friend) functions? Or does it matter at all? Maybe there is a best practice for this?

Edit
Report

3 Answers

19

Each operator has its own considerations. For example, the << operator (when used for stream output, not bit shifting) gets an ostream as its first parameter, so it can't be a member of your class. If you're implementing the addition operator, you'll probably want to benefit from automatic type conversions on both sides, therefore you'll go with a non-member as well, etc...

As for allowing specialization through inheritance, a common pattern is to implement a non-member operator in terms of a virtual member function (e.g. operator<< calls a virtual function print() on the object being passed).

answered 2009-12-15T06:16:22.173
6

If you plan on implementing streaming operators (<< and >>) then they will be non-members methods because your object is on the left of the operator.

If you plan on implementing ->, () or [] they are naturally member methods.

For the others (comparison and mathematical) you should check out Boost.Operators, it really helps.

For example, if you want to implement the following operators:

MyClass& MyClass::operator+=(int);
MyClass operator+(const MyClass&, int);
MyClass operator+(int, const MyClass&);

You only have to write:

class MyClass: boost::operator::addable<MyClass,int> // no need for public there
{
public:
  MyClass& operator+=(int);
private:
};

The 2 operator+ will be automatically generated as non-members which will let you benefit from automatic conversions. And they will be implemented efficiently in term of operator+= so you write code only once.

answered 2009-12-15T10:23:39.567
3

For binary operators, one limitation of member functions is that the left object must be of your class type. This can limit using the operator symmetrically.

Consider a simple string class:

class str
{
public:
    str(const char *);
    str(const str &other);
};

If you implement operator+ as a member function, while str("1") + "2" will compile, "1" + str("2") will not compile.

But if you implement operator+ as a non-member function, then both of those statements will be legal.

answered 2009-12-15T06:56:10.067

Your Answer