2012-10-09 37 views
21

我试图覆盖一个类的<<操作符。目的基本上是为我的课程实施类似toString()的行为,以便将它发送到cout将产生有用的输出。使用一个虚拟的例子,我有下面的代码。当我试图编译时,我得到了错误:C++操作符的多重定义<<

$ 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 

我不明白为什么会发生这种情况。我的代码如下:

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; 
} 

回答

33

你打破了一个定义规则。快速修复是:

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

其他是:

  • 声明在头文件中的运营商和移动实施Rectangle.cpp文件。
  • 在类定义中定义运算符。

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; 
     } 
}; 

加成:

  • 使用包括警卫
  • 从头部取下using namespace std;
+0

*在成员定义的情况:*如果上面的'CRectangle'以及'超载<<'其他的类定义它使用'CRectangle'的'''然后有问题。即使在做“CRectangle”的前向声明!任何想法为什么? – Paschalis

10

你把定义函数在.h文件,这意味着它会出现在每一个翻译单元,违反了一个定义规则(=>你的每一个对象模块中定义operator<<,所以链接器不知道哪一个是“正确的”)。

您可以:

  • 写只是你的运营商(即其原型)在.h文件并移动其定义的声明rectangle.cpp
  • 使operator<<inline - inline功能允许定义不止一次,只要所有定义相同即可。

(此外,你应该使用头卫兵在包括。)