【问题标题】:c++ multiple definitions of operator<<c++ operator<<的多重定义
【发布时间】:2012-09-29 22:22:21
【问题描述】:

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

我不知道为什么会这样。我的代码如下:

矩形.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;
}

矩形.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;
}

【问题讨论】:

    标签: c++ overriding iostream operator-keyword


    【解决方案1】:

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

    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;

    【讨论】:

    • 在成员定义的情况下:如果在CRectangle之上还有另一个类定义在overload&lt;&lt;中它使用&lt;&lt;&lt;&lt;然后有问题。即使在进行CRectangle 的前向声明时!知道为什么吗?
    【解决方案2】:

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

    您可以:

    • 在 .h 文件中只写你的操作符(即它的原型)的声明并将它的定义移动到rectangle.cpp
    • make operator&lt;&lt; inline - inline 函数可以多次定义,只要所有定义相同。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多