.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();
....
}
当我尝试在 .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();
....
}