首页 > 解决方案 > .h 文件中 << 运算符的重载

问题描述

当我尝试在我的 .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
}

标签: c++operator-overloadingoperatorsmingw

解决方案


因为你的 .h 文件是从多个 .cpp 文件中包含的,并且每个 .cpp 文件被分别编译为不同的编译单元,然后链接在一起,因此,您的 << 运算符函数将在每个编译单元中,并且它们发生冲突在链接阶段彼此。

如果您坚持将其保留在 .h 文件中,则有两种选择。

选项1:

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

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

选项2:

使 << 运算符成为静态函数。但是您需要先将函数声明为静态,然后再将其声明为友元。

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

在友元声明中首次声明的函数具有外部链接(3.5)。否则,该函数将保留其先前的链接(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();
   ....
}

推荐阅读