An external method (like point operator- (const point& obj,const point& obj2);) can be auto generated using templates sometimes. Whereas the class specific version should be thought of a specialisation.
A different example is std::find(). It's applies a linear search (to containers that meet certain criteria), but containers that can do better provide their own find().
Both the operators that you have defined are supposed to do the same thing, so there is no reason to define both of them.
If you use operator- in code it will prefer the the member function.
1 2 3 4 5 6 7
point p1(2);
point p2(3);
point p3 = (p1 - p2);
p1.print();
p2.print();
p3.print();
x:-1 y:-1
x:3 y:3
x:-1 y:-1
This implementation is by the way faulty because it changes the value of p1, which is not what you would expect. It also gives the wrong result if you subtract a point to itself.
If you comment out the member function it will instead use the friend function, which happens to be correctly implemented giving the expected output.
I guess one difference is that, if you had an object of a type that defined a conversion operator to point, then you could use it as the first operand of the friend function. So, if you had:
1 2 3 4 5 6 7 8 9 10 11
#include "point.h"
class SomethingElse
{
point m_point;
public:
operator point()
{
return m_point;
};
};
Then, with the friend function operator, you could do:
1 2 3 4 5 6 7 8
point a;
SomethingElse b;
// Do some initialisation first
// ...
// Now subtract
point result = b - a;
The compiler knows that SomethingElse can be converted to a point, so it can be implicitly converted and used as the first argument of the friend function operator. If you only had the member operator, then you couldn't do that - you'd have to explicitly cast (or copy) b to a point first.
(I'm happy to be corrected if I'm wrong, by the way - it's a very long time since I've needed to look up how implicit conversion works).