c ++运算符的多个定义<<

时间:2012-10-09 14:41:01

标签: c++ override iostream operator-keyword

我正在尝试覆盖类的<<运算符。目的基本上是为我的类实现类似toString()的行为,以便将其发送到cout将产生有用的输出。使用一个虚拟示例,我有下面的代码。当我尝试编译时,我得到了一个愚蠢的错误:

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

2 个答案:

答案 0 :(得分:40)

您违反了一个定义规则。快速解决方法是:

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;

答案 1 :(得分:14)

您将函数的定义放在.h文件中,这意味着它将出现在每个翻译单元中,违反了一个定义规则(=&gt;您定义的{ {1}}在每个对象模块中,因此链接器不知道哪个是“正确的”。)

你可以:

  • 在.h文件中只编写运算符的声明(即其原型),并将其定义移至operator<<
  • make rectangle.cpp operator<< - inline函数可以多次定义,只要所有定义都相同。

(另外,你应该在你的包中使用标题保护。)