.h 文件中 << 运算符的重载

Overload of << operator in .h files

当我尝试在 .h 文件中重载“<<”运算符时,出现以下错误:

multiple definition of `operator<<(std::ostream&, complex_number&)' 

但是当我在我的 .cpp 文件中移动运算符重载时,一切正常。 我真的不知道发生了什么。有帮助吗?

这是我的初始代码:

(main.cpp真的很简单,不包含任何重要的东西)

complex_number.h

#ifndef COMPLEX_NUMBER_H
#define COMPLEX_NUMBER_H

#include <iostream>

using namespace std;


class complex_number
{
    public:
        complex_number();
        complex_number(double, double);
        virtual ~complex_number();

        double Geta() const { return a; }
        void Seta(double val) { a = val; }
        double Getb() const { return b; }
        void Setb(double val) { b = val; }

        void print();

        friend ostream & operator << (ostream &out, complex_number &cmp);

    protected:

    private:
        double a;
        double b;

};

ostream & operator << (ostream &out, complex_number &cmp) {
    double a = cmp.Geta();
    double b = cmp.Getb();
    if (a == 0 && b == 0){
        out << "0";
    }
    else if (a == 0) {
        //if (b < 0) cout << "-";
        if   (b == -1) {
            out << "-i";
        }
        if (b!=1) cout << b;
        out << "i";
    }
    else if (b == 0) {
        out << a;
    } else {
        out << a;
        out << (b > 0 ? "+" : "-");
        if (b!=1 && b!=-1) out << (b > 0 ? b : -1*b);
        out << "i";
    }

    return out;

}


#endif // COMPLEX_NUMBER_H

complex_number.cpp

#include "complex_number.h"
#include <iostream>
#include <string>

using namespace std;

complex_number::complex_number()
{
    //ctor
    a = 0;
    b = 0;
}

complex_number::complex_number(double a1, double b1)
{
    //ctor
    a = a1;
    b = b1;
}

void complex_number::print() {

    if (a == 0 && b == 0){
        cout << "0";
        return;
    }
    else if (a == 0) {
        //if (b < 0) cout << "-";
        if   (b == -1) {
            cout << "-i";
            return;
        }
        if (b!=1) cout << b;
        cout << "i";
        return;
    }
    else if (b == 0) {
        cout << a;
        return;
    }

    cout << a;
    cout << (b > 0 ? "+" : "-");
    if (b!=1) cout << (b > 0 ? b : -1*b);
    cout << "i";
    return;


}

complex_number::~complex_number()
{
    //dtor
}

因为你的 .h 文件是从多个 .cpp 文件中包含的,并且每个 .cpp 文件都是作为不同的编译单元单独编译的,然后 linked 在一起,因此,你的 << 运算符函数将是在每个编译单元中,它们在 link 阶段相互冲突。

如果你坚持把它留在.h文件中,有两种选择。

选项 1:

内联<<运算符,内联函数会像宏一样展开,不会为函数生成符号,因此不会产生冲突:

inline ostream & operator << (ostream &out, complex_number &cmp) {

选项 2:

使 << 运算符成为静态函数。但是在将其声明为友元之前,您需要将该函数声明为静态的。

原因是: 引用 N3691 - §11.3/4 [class.friend]

首先在友元声明中声明的函数具有外部 linkage (3.5)。否则,该函数将保留其之前的 linkage (7.1.1).

complex_number.h

class complex_number;
static ostream & operator << (ostream &out, complex_number &cmp);

class complex_number
{
    public:
        complex_number();
        complex_number(double, double);
        virtual ~complex_number();

        double Geta() const { return a; }
        void Seta(double val) { a = val; }
        double Getb() const { return b; }
        void Setb(double val) { b = val; }

        void print();

        friend ostream & operator << (ostream &out, complex_number &cmp);

    protected:

    private:
        double a;
        double b;

};

static ostream & operator << (ostream &out, complex_number &cmp) {
    double a = cmp.Geta();
   ....
}