0

In my code I have 2 classes declared in header "Geometry.h", Vector & Point. Inside Point class, I have following:

class Point {
// other stuff
    friend Vector operator-(const Point& lhs, const Point& rhs);
}

Vector is defined in "Vector.cpp" & Point is defined in "Point.cpp".

My compiler (GCC) complains about this and I don't know why:

undefined reference to `Geometry::operator-(Geometry::Point const&, Geometry::Point const&)'|

Definition of function in "Point.cpp" looks like this:

Vector operator-(const Point& lhs,
             const Point& rhs)
{
    return Vector(lhs.GetX()-rhs.GetX(),lhs.GetY()-rhs.GetY());
}
BartoszKP
  • 34,786
  • 15
  • 102
  • 130
Alexander Bily
  • 925
  • 5
  • 18
  • 5
    And is that definition inside `namespace Geometry`? – aschepler Aug 21 '14 at 12:01
  • at the start of the cpp file I have "using Geometry::Point; using Geometry::Vector;" Is that fine with friend functions or may that be reason why it doesnt compile? – Alexander Bily Aug 21 '14 at 12:07
  • 1
    @AlexanderBily aschepler asked about the *definition* of the operator, i.e. last code block in your question. It should be inside the `Geometry` namespace (i.e. `namespace Geometry { Vector operator-(const Point& ... }`). – BartoszKP Aug 21 '14 at 12:12
  • So the friend operator declared in class doesnt belong to that class scope? Thanks for your help I changed it so everything is defined inside namespace instead of "using" and it works. – Alexander Bily Aug 21 '14 at 12:14
  • @AlexanderBily That's only information that this particular function is a friend of this class. It doesn't have anything to do with where is this function defined (however, there is a special syntax that allows you to declare friendship & define the function at the same time. I'd not recommend it however). – BartoszKP Aug 21 '14 at 12:24
  • As a side note, you could also add `operaror-=` within the class and then use this operaror in your out-of-class `operator-` without the need to make it a friend. – aaragon Aug 21 '14 at 13:02
  • Just for information is there any performance overhead for one more function call or does compiler optimizes calls like this away? – Alexander Bily Aug 21 '14 at 13:08
  • @aaragon `operator-` can only be implemented in terms of `operator-=` when the result type is the same class, but that's not the case here. – aschepler Aug 21 '14 at 13:28
  • Oh that's true! Which makes you wonder if there's a design issue here. As subtracting apples from apples should give you apples. – aaragon Aug 21 '14 at 13:31

1 Answers1

2

As you have discovered in a discussion, you should put your operator- code in your namespace:

namespace Geometry
{
    ...
    Vector operator-(const Point& lhs, const Point& rhs)
    {
        return Vector(lhs.GetX()-rhs.GetX(),lhs.GetY()-rhs.GetY());
    }
}

There is an alternative way to put it into a namespace:

Vector Geometry::operator-(const Point& lhs, const Point& rhs)
{
    return Vector(lhs.GetX()-rhs.GetX(),lhs.GetY()-rhs.GetY());
}
anatolyg
  • 26,506
  • 9
  • 60
  • 134