53

I am attempting to override the << operator for a class. The purpose is basically to implement a toString() like behavior for my class, so that sending it to cout will produce useful output. Using a dummy example, I have the code below. When I attempt to compile, I get the foollowing error:

$ g++ main.cpp Rectangle.cpp
/tmp/ccWs2n6V.o: In function `operator<<(std::basic_ostream<char, std::char_traits<char> >&, CRectangle const&)':
Rectangle.cpp:(.text+0x0): multiple definition of `operator<<(std::basic_ostream<char, std::char_traits<char> >&, CRectangle const&)'
/tmp/ccLU2LLE.o:main.cpp:(.text+0x0): first defined here

I can't figure out why this is happening. my code is below:

Rectangle.h:

#include <iostream>
using namespace std;

class CRectangle {
    private:
        int x, y;
        friend ostream& operator<<(ostream& out, const CRectangle& r);
    public:
        void set_values (int,int);
        int area ();
};

ostream& operator<<(ostream& out, const CRectangle& r){
    return out << "Rectangle: " << r.x << ", " << r.y;
}

Rectangle.cpp:

#include "Rectangle.h"

using namespace std;

int CRectangle::area (){
    return x*y;
}

void CRectangle::set_values (int a, int b) {
    x = a;
    y = b;
}

main.cpp:

#include <iostream>
#include "Rectangle.h"

using namespace std;

int main () {
    CRectangle rect;
    rect.set_values (3,4);
    cout << "area: " << rect.area();
    return 0;
}

2 Answers 2

76

You're breaking the one definition rule. A quick-fix is:

inline ostream& operator<<(ostream& out, const CRectangle& r){
    return out << "Rectangle: " << r.x << ", " << r.y;
}

Others are:

  • declaring the operator in the header file and moving the implementation to Rectangle.cpp file.
  • define the operator inside the class definition.

.

class CRectangle {
    private:
        int x, y;
    public:
        void set_values (int,int);
        int area ();
        friend ostream& operator<<(ostream& out, const CRectangle& r){
          return out << "Rectangle: " << r.x << ", " << r.y;
        }
};

Bonus:

  • use include guards
  • remove the using namespace std; from the header.
1
  • In the case of member definition: If there is another class definition above the CRectangle and in the overload<< it uses the << of CRectangle then there are issues. Even when doing a forward declaration of CRectangle! Any idea why?
    – Paschalis
    Commented Apr 28, 2016 at 16:55
29

You are putting the definition of a function in a .h file, which means that it will appear in every translation unit, violating the One Definition Rule (=> you defined operator<< in every object module, so the linker doesn't know which is "the right one").

You can either:

  • write just the declaration of your operator (i.e. its prototype) in the .h file and move its definition to rectangle.cpp
  • make operator<< inline - inline functions are allowed to be defined more than once, as long as all the definitions are identical.

(Also, you should use header guards in your includes.)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.