1

Assume that I have the following basic class where I want to overload operator+:

class foo {
private:
    arbitrary datatype

public:
    foo() { set private data; };
    virtual ~foo() {};

};

I've always used this format:

foo operator+( const foo &rhs );

However, I've recently stumbled onto some code where the person exclusively used:

friend foo operator+( const foo &lhs, const foo &rhs );

So, is it standard to use one version over the other? Are there situations where you would be forced into one version (This is only for adding the same object types)? I'm not familiar with assembly language, but would the compiler convert these into the same list of instructions (This question is obviously dependent on answers to the first 2)?

TriHard8
  • 592
  • 6
  • 18
  • The one-argument version is for when the operator is a *member* function, the two-argument version is a stand-alone (non-member) function. Some operators can only be implemented using member-functions, but for the others it's up to you as a designer and implementer to decide what you prefer. Also remember that member functions can of course access private data, while non-friend non-member function can't. – Some programmer dude Feb 19 '15 at 04:31
  • Also: http://stackoverflow.com/q/6255825/560648 – Lightness Races in Orbit Feb 20 '15 at 01:04

1 Answers1

3
  1. To answer your first 2 questions

    It is recommended (but not enforced) to use the friend approach for binary operators because it allows to have objects that are convertible to your class on the left hand side of the operator. Consider this:

    class Foo
    {
        // private members
    public:
        Foo(int) {/* ctor implementation */} // implicit convertible to int
        Foo(const Foo&) { /* copy ctor implementation */ }
        friend Foo operator+(const Foo& lhs, const Foo& rhs){/* implementation */}
    };
    

    Now you can do:

    Foo foo1{1};
    Foo foo2 = 1 + foo1; // 1 is implicitly converted to Foo here
    

    If operator+ would have been a member function, the call above would fail (left hand side, even if convertible to Foo, will not be automatically converted by the compiler), and you'd be only able to use

    Foo foo2 = foo1 + 1;
    

    So, in conclusion, using friend for binary operators make them more "symmetric".

  2. Last question:

    The assembler would not generate the same code, as the friend/member operator+ are doing slightly different things.

See also a very good guide about overloading operators here.

Community
  • 1
  • 1
vsoftco
  • 55,410
  • 12
  • 139
  • 252
  • Ah, cool, I didn't realize that. So, to understand what's going on, is the '1' in `Foo foo2 = 1 + foo1` automatically tossed into a constructor? That looks like what happened in my program where I'm applying this. – TriHard8 Feb 19 '15 at 04:42
  • Yes, `foo2` is copy constructed from the result of `operator+(Foo{1}, foo1)` – vsoftco Feb 19 '15 at 04:42
  • @TriHard8 and yes, `1` on the lhs is automatically casted into `Foo{1}` then passed to `operator+` – vsoftco Feb 19 '15 at 04:49