1

I have implemented two operator overloading for Point2D class

  1. operator<
  2. operator>

In header file I need to declare as friend function otherwise i get compilation errors.
Question : Are operator overloading functions always friend functions? Can it be static? I tried using as static function but there's an error:

Point2D.h:19:58: error: ‘static bool Point2D::operator<(const Point2D&, const Point2D&)’ must be either a non-static member function or a non-member function
In file included from Point2D.cpp:3:0:
Point2D.h:19:58: error: ‘static bool Point2D::operator<(const Point2D&, const Point2D&)’ must be either a non-static member function or a non-member function
Point2D.h: In function ‘bool operator<(const Point2D&, const Point2D&)’:
Point2D.h:23:7: error: ‘int Point2D::x’ is protected
Point2D.cpp:36:11: error: within this context
Point2D.h:24:7: error: ‘int Point2D::y’ is protected
Point2D.cpp:36:17: error: within this context

class Point2D
{

    friend ostream &operator<<( ostream &output, const Point2D &P);
    friend bool operator<(const Point2D& A, const Point2D& B);
    friend bool operator>(const Point2D& A, const Point2D& B);      

    protected:  
        int x;
        int y;
    public:
        //Constructor
        Point2D();
        Point2D (int x, int y);

        //Accessors
        int getX();
        int getY();

        //Mutators
        void setX (int x);
        void setY (int y);
};


ostream &operator<<( ostream &output, const Point2D &P)
              { 
             output << "X : " << P.x << "Y : " << P.y;
             return output;            
              }

    bool operator<(const Point2D& A, const Point2D& B ) 
    {
        return A.x < B.y;
    };


    bool operator>(const Point2D& A, const Point2D& B ) 
    {
        return A.x > B.y;
    };
Amith
  • 6,818
  • 6
  • 34
  • 45
user23
  • 415
  • 1
  • 8
  • 22

3 Answers3

2

Binary operators could be implemented as global binary functions, or unary member functions. In the latter, the first operand of the operator is passed implicitly (Is *this, as in all member functions):

Option 1: Global function

struct foo
{
    int a;
};

bool operator==( const foo& lhs , const foo& rhs )
{
    return lhs.a == rhs.b;
}

Option 2: Member function

struct foo
{
    int a;

    bool operator==( const foo& rhs )
    {
//             +---- this->a
//             |
//             v
        return a == rhs.a;
    }
};

Option 3: Global function inside the class, declared as friend (My favorite)

struct foo
{
    int a;

    friend bool operator==( const foo& lhs , const foo& rhs )
    {
        return lhs.a == rhs.b;
    }
};

For a complete and in depth guide about operator overloading, check this C++ wiki thread: Operator overloading

Community
  • 1
  • 1
Manu343726
  • 13,969
  • 4
  • 40
  • 75
  • can i implement as static boolean functions? that's one of the requirement I need to implement. Thanks. – user23 Nov 16 '13 at 18:14
  • @kbear no, you can't. As you can see, you define an overload of an existing operator to work with your class, not define an operator of your class. Note the point. Thats why operators are not static. – Manu343726 Nov 16 '13 at 18:17
  • i see. actually i have to implement the same function comparators ideally for 4 classes as static boolean functions. and Point2D is one of them. – user23 Nov 16 '13 at 18:27
  • @kbear The point is: C++ has no comparison functions, has **comparison operators**. Implement them. Learn/Use the way the language works, not the way you wan't it work. – Manu343726 Nov 16 '13 at 18:30
  • @kbear: *I have to implement* => why do you think so ? – Matthieu M. Nov 16 '13 at 18:31
  • @kbear thats the `operator<=()`. Overload it. – Manu343726 Nov 16 '13 at 18:35
  • When I say "have to", it's just a requirement for my assignment. :) I'm just asking if it's possible to implement as static functions. Thanks for all your help everyone. – user23 Nov 16 '13 at 18:36
  • @kbear read about comparison functors, that could be an elegant solution more near to your requirement. Also, note that (Except if he/she has a very good reason to use a `static` comparator) seems like your teacher does not know C++ very well. Accept please. – Manu343726 Nov 16 '13 at 18:38
0

Change your overloading functions to this:

friend ostream &operator<<( ostream &output, const Point2D &);
bool operator<(const Point2D&);
bool operator>(const Point2D&);   

bool operator<(const Point2D& B ) 
{
    return x < B.x && y < B.y;
}


bool operator>(const Point2D& B ) 
{
    return x > B.x && y > B.y;
}

friend ostream &operator<<( ostream &output, const Point2D &P)
{ 
    output << "X : " << P.x << "Y : " << P.y;
    return output;            
}

Alternatively, you can make them all friend functions:

friend ostream &operator<<( ostream &output, const Point2D &);
friend bool operator<(const Point2D&, const Point2D&);
friend bool operator>(const Point2D&, const Point2D&);   

friend bool operator<(const Point2D& A, const Point2D& B ) 
{
    return A.x < B.x && A.y < B.y;
}


friend bool operator>(const Point2D& A, const Point2D& ) 
{
    return A.x > B.x && A.y > B.y;
}

friend ostream &operator<<( ostream &output, const Point2D &P)
{ 
    output << "X : " << P.x << "Y : " << P.y;
    return output;            
}

In general, you make create a friend overload if you want that function to have access to private members of the class. If you don't need it to have access to private members, then simply strip off the friend label and declare the function outside the class.

smac89
  • 39,374
  • 15
  • 132
  • 179
  • Point2D.h:19:65: error: storage class specifiers invalid in friend function declarations In file included from Point2D.cpp:3:0: Point2D.h:19:65: error: storage class specifiers invalid in friend function declarations Point2D.cpp: In function ‘bool operator<(const Point2D&, const Point2D&)’: Point2D.cpp:34:58: error: ‘bool operator<(const Point2D&, const Point2D&)’ was declared ‘extern’ and later ‘static’ [-fpermissive] – user23 Nov 16 '13 at 18:38
  • The error is saying that you have declared the overload for operator `<` somewhere else before declaring it static. You have to make all declarations static if you want to use static version. Otherwise you will have the compiler whining for no reason – smac89 Nov 16 '13 at 18:47
  • Declaring an static function as friend as no sense at all. As any other member function, it has access to private/protected members of the class. The only difference is that is doesn't have a `this` pointer. – Manu343726 Nov 16 '13 at 18:49
0

Your comparison operators need not be friend, unless you need to access a non-public member which can not otherwise be accessed. In this case, you can use your accessor function getX() and getY()

Like:

// Have a declaration for operator < after the Point2D class in the header file. Not inside as a friend.

// Global operator <
bool operator<(const Point2D& A, const Point2D& B ) 
{
    return A.getX() < B.getX();
};

Its worth noting that comparison operators are typically a member of the class. Stream manipulation operators like << & >> are non-members and optionally friend. But, its not always necessary to make comparison operators a member function.

UltraInstinct
  • 43,308
  • 12
  • 81
  • 104
  • *"Your operator overloaded functions are friend to the class, meaning they are not a member of the class. This means, as the error says, you can not access non-public members."* The purpose of the `friend`keyword is to skip encapsulation, so even if the function is not memeber of the class, it has access to private members of class variables. – Manu343726 Nov 16 '13 at 18:15
  • You are right, That line belonged to another paragraph that I deleted in one edit. I will edit it again. – UltraInstinct Nov 16 '13 at 18:16
  • 1
    The whole point of `friend` is to give access to the private members. – Alan Stokes Nov 16 '13 at 18:18
  • *"Its worth noting that comparison operators are typically a member of the class"* Thats not true. Global or friend binary operators have the advantage that it allows you to specify a first operand which its type is not the class itself. Thats why I prefer `friend` (Also allows me to automatice operator overloading through the Barton-Nackman trick) – Manu343726 Nov 16 '13 at 18:24
  • @Manu343726 Hmm, thats actually a good trick. Never knew about that before. Thanks! :) – UltraInstinct Nov 16 '13 at 18:30
  • Check [boost::operators API](http://www.boost.org/doc/libs/1_34_0/libs/utility/operators.htm). This trick is nowadays deprecated by ADL, but I use it because it allows you to specify easilly what operators your class overload and what not. – Manu343726 Nov 16 '13 at 18:33
  • Why would you check X against Y? – Zac Howland Nov 16 '13 at 18:46
  • 1
    @ZacHowland Oops, another typo! Damn, I should be catching some sleep may be. Thanks for pointing :) – UltraInstinct Nov 16 '13 at 18:48