定义 ostream 运算符的友元函数
Friend function defining an ostream operator
我想定义一个 ostream 运算符,让我轻松输出 alglib::complex
类型的变量。为了提供一个不包含 alglib 库的工作示例,我将在下面重载 complex<double>
的输出(此说明是由于问题的早期版本)。在头文件中 "my_class.h" 我有
using namespace std;
#include <complex>
#include <iostream>
class my_class {
public:
ostream& operator << (std::ostream& os, complex<double> a) {
os << "(" << real(a) << "," << imag(a) << ")";
return os;
}
void output(complex<double>);
my_class() {}
~my_class() {}
};
在源文件中 "my_class.cpp" 我有
#include "my_class.h"
void my_class::output(complex<double> cd) {
cout << cd << endl;
}
终于有了主方法文件"run_my_class.cpp":
#include "my_class.h"
int main(int argc, const char* argv[]) {
my_class obj;
complex<double> cd=complex<double>(1.0,-1.0);
obj.output(cd);
}
我尝试使用
编译
g++ -c my_class.cpp
但这给了我错误
my_class.h:9:62: error: ‘std::ostream& my_class::operator<<(std::ostream&, std::complex<double>)’ must take exactly one argument
ostream& operator << (std::ostream& os, complex<double> a) {
但是,如果我将运算符定义为朋友,即friend ostream& operator << (std::ostream& os, complex<double> a)
,它会编译,我会编译主要方法:
g++ run_my_class.cpp my_class.o -o run_my_class
它可以正常工作。然而,这并不是 friend
关键字的用途。有没有更好的方法来完成这项工作?
由于 operator <<
将在 std::ostream
上调用,您不能将此过程定义为 my_class
的 成员函数 ,您有将其定义为 全局函数 ,因为它是 std::ostream
的操作,而不是 my_class
.
通过将 friend
关键字放入声明中,您是说要将 operator <<
声明为友元 全局函数(不是成员函数!)。 C++ 标准允许您将友元函数的定义放在那里,但它不会是成员函数。和下面一样,更清楚:
#include <complex>
#include <iostream>
class my_class {
public:
friend ostream& operator << (std::ostream& os, complex<double> a);
void output(complex<double>);
my_class() {}
~my_class() {}
};
std::ostream& operator << (std::ostream& os, complex<double> a) {
os << "(" << real(a) << "," << imag(a) << ")";
return os;
}
正如评论中已经指出的那样,这里不需要使用 friend
。
与问题无关,但请注意,在头文件中解析命名空间通常是一个非常非常糟糕的主意,因为包括它在内的所有其他文件也会隐式解析该命名空间。它很容易导致长 运行.
中令人烦恼的编译错误
我不会称之为更好的方式,而是更清晰的方式。
又是你的流媒体运营商:
ostream& operator << (std::ostream& os, complex<double> a) {
os << "(" << real(a) << "," << imag(a) << ")";
return os;
}
它的第一个参数是输出流。由于您无权访问输出流,因此不能将输出流运算符用作成员函数,除非您使其成为 class.
的友元
如果您想避免使用 friend,您始终可以将其定义为 class 之外的函数,这是最常见的方式。
我想定义一个 ostream 运算符,让我轻松输出 alglib::complex
类型的变量。为了提供一个不包含 alglib 库的工作示例,我将在下面重载 complex<double>
的输出(此说明是由于问题的早期版本)。在头文件中 "my_class.h" 我有
using namespace std;
#include <complex>
#include <iostream>
class my_class {
public:
ostream& operator << (std::ostream& os, complex<double> a) {
os << "(" << real(a) << "," << imag(a) << ")";
return os;
}
void output(complex<double>);
my_class() {}
~my_class() {}
};
在源文件中 "my_class.cpp" 我有
#include "my_class.h"
void my_class::output(complex<double> cd) {
cout << cd << endl;
}
终于有了主方法文件"run_my_class.cpp":
#include "my_class.h"
int main(int argc, const char* argv[]) {
my_class obj;
complex<double> cd=complex<double>(1.0,-1.0);
obj.output(cd);
}
我尝试使用
编译g++ -c my_class.cpp
但这给了我错误
my_class.h:9:62: error: ‘std::ostream& my_class::operator<<(std::ostream&, std::complex<double>)’ must take exactly one argument
ostream& operator << (std::ostream& os, complex<double> a) {
但是,如果我将运算符定义为朋友,即friend ostream& operator << (std::ostream& os, complex<double> a)
,它会编译,我会编译主要方法:
g++ run_my_class.cpp my_class.o -o run_my_class
它可以正常工作。然而,这并不是 friend
关键字的用途。有没有更好的方法来完成这项工作?
由于 operator <<
将在 std::ostream
上调用,您不能将此过程定义为 my_class
的 成员函数 ,您有将其定义为 全局函数 ,因为它是 std::ostream
的操作,而不是 my_class
.
通过将 friend
关键字放入声明中,您是说要将 operator <<
声明为友元 全局函数(不是成员函数!)。 C++ 标准允许您将友元函数的定义放在那里,但它不会是成员函数。和下面一样,更清楚:
#include <complex>
#include <iostream>
class my_class {
public:
friend ostream& operator << (std::ostream& os, complex<double> a);
void output(complex<double>);
my_class() {}
~my_class() {}
};
std::ostream& operator << (std::ostream& os, complex<double> a) {
os << "(" << real(a) << "," << imag(a) << ")";
return os;
}
正如评论中已经指出的那样,这里不需要使用 friend
。
与问题无关,但请注意,在头文件中解析命名空间通常是一个非常非常糟糕的主意,因为包括它在内的所有其他文件也会隐式解析该命名空间。它很容易导致长 运行.
中令人烦恼的编译错误我不会称之为更好的方式,而是更清晰的方式。
又是你的流媒体运营商:
ostream& operator << (std::ostream& os, complex<double> a) {
os << "(" << real(a) << "," << imag(a) << ")";
return os;
}
它的第一个参数是输出流。由于您无权访问输出流,因此不能将输出流运算符用作成员函数,除非您使其成为 class.
的友元如果您想避免使用 friend,您始终可以将其定义为 class 之外的函数,这是最常见的方式。