c++ - .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
}
解决方案
因为你的 .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();
....
}
推荐阅读
- ajax - 在 laravel 5.7.14 中使用命名空间时出现此错误
- gradle - Android Gradle 插件:将 NDK 可执行文件打包到 APK 中
- javascript - 当我使用模板文字并运行代码时,结果未定义
- python - 涉及序列的任务需要多少个 RNN 单元?
- testing - 如何在jmeter中每25分钟运行一个线程
- javascript - Reactjs Facebook 登录库的问题 - 使 componentClicked 函数异步
- highcharts - Highstock 工具提示“标签”未呈现
- r - R/闪亮的数据框列
- python - Tinkerpop & Python - 通过 gremlin 设置数组属性
- python - 如何用 pandas DataFrame 中的共享列值替换某些行?