C++中operator<<出现多重定义

50

我正在尝试为一个类覆盖<<运算符。目的基本上是为了实现类似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;
}

主程序.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个回答

72

你正在违反单一定义规则。一个快速解决办法是:

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

额外提示:

  • 使用 include guards
  • 从头文件中移除 using namespace std;

在成员定义的情况下:如果在CRectangle上方有另一个类定义,并且在overload<<中使用了CRectangle<<,那么就会出现问题。即使进行了CRectangle的前向声明!你知道为什么吗? - Paschalis

27
您将函数的定义放在了一个.h文件中, 这意味着它会出现在每个翻译单元中, 违反了一个定义规则(=> 您在每个对象模块中都定义了operator<<, 因此链接器不知道哪个才是"正确的")。
您可以选择:
  • 只在.h文件中写下operator的声明(即其原型), 并将其定义移动到rectangle.cpp中
  • 将operator<<定义为inline - inline函数允许被多次定义,只要所有的定义相同。
(此外, 您应该在包含文件中使用头保护。)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接