C++ 运算符<<的多重定义

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12802536/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 16:38:13  来源:igfitidea点击:

c++ multiple definitions of operator<<

c++overridingiostreamoperator-keyword

提问by ewok

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 coutwill produce useful output. Using a dummy example, I have the code below. When I attempt to compile, I get the foollowing error:

我试图覆盖<<一个类的运算符。目的基本上是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

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

我不明白为什么会这样。我的代码如下:

Rectangle.h:

矩形.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:

矩形.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:

主.cpp:

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

using namespace std;

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

回答by Luchian Grigore

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.cppfile.
  • define the operator inside the class definition.
  • 在头文件中声明操作符并将实现移动到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;
        }
};

Bonus:

奖金:

  • use include guards
  • remove the using namespace std;from the header.
  • 使用包括警卫
  • using namespace std;从标题中删除。

回答by Matteo Italia

You are putting the definitionof a function in a .hfile, 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").

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

You can either:

您可以:

  • write just the declarationof your operator (i.e. its prototype) in the .h file and move its definition to rectangle.cpp
  • make operator<<inline- inlinefunctions are allowed to be defined more than once, as long as all the definitions are identical.
  • 在 .h 文件中只写你的操作符(即它的原型)的声明,并将其定义移动到rectangle.cpp
  • make operator<<inline-inline允许多次定义函数,只要所有定义都相同。

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

(此外,您应该在包含中使用标题保护。)