如何正确重载<<运算符一个ostream?
-
20-08-2019 - |
题
我写在C语言的小矩阵库++用于矩阵运算。但是我的编译器抱怨,而以前并非如此。此代码是留下了货架上6个月,并在两者之间我已经升级,从Debian的蚀刻我的计算机到lenny的(G ++(Debian的4.3.2-1.1)4.3.2 )但是我有同样的问题一个Ubuntu系统具有相同的克++上。
下面是我的矩阵类的相关部分:
namespace Math
{
class Matrix
{
public:
[...]
friend std::ostream& operator<< (std::ostream& stream, const Matrix& matrix);
}
}
和 “实施”:
using namespace Math;
std::ostream& Matrix::operator <<(std::ostream& stream, const Matrix& matrix) {
[...]
}
这是由编译器给出的错误:
matrix.cpp:459:错误:“的std :: ostream的& 数学::矩阵::运算符<<(STD :: ostream的和, 常量数学::矩阵和)”必须采取 且只有一个参数
我有点被这个错误感到困惑,但随后再次我C ++已经得到了做大量的Java的这6个月后,有点生疏。 : - )
解决方案
您已经声明了功能friend
。这不是类的成员。你应该从实现删除Matrix::
。 friend
指指定的功能(这是不是类的成员)可以访问私有成员变量。你实现的功能的方法是像Matrix
类的实例方法,该方法是错误的。
其他提示
只是告诉你一个大概的另一种可能性:我喜欢用朋友的定义为:
namespace Math
{
class Matrix
{
public:
[...]
friend std::ostream& operator<< (std::ostream& stream, const Matrix& matrix) {
[...]
}
};
}
功能将被自动定位到周围的命名空间Math
(即使它的定义出现该类别的范围内),但除非你调用operator <<与Matrix对象,这将使参数依赖查找发现,将不可见运营商的定义。可以用暧昧的电话,有时帮助,因为它比其他矩阵参数类型不可见。当写的定义,你也可以直接引用在矩阵定义的名称和基体本身,而不与一些可能长的前缀限定名称,并提供像Math::Matrix<TypeA, N>
模板参数。
要添加到迈赫达德答案,
namespace Math
{
class Matrix
{
public:
[...]
}
std::ostream& operator<< (std::ostream& stream, const Math::Matrix& matrix);
}
在您的实施
std::ostream& operator<<(std::ostream& stream,
const Math::Matrix& matrix) {
matrix.print(stream); //assuming you define print for matrix
return stream;
}
假设我们谈论过载operator <<
从std::ostream
衍生处理Matrix
类的所有类(和不为过载类<<
Matrix
),它更有意义申报在报头中的数学名称空间外的过载功能。
使用仅当功能不能经由公共接口来实现的朋友功能。
<强> Matrix.h 强>
namespace Math {
class Matrix {
//...
};
}
std::ostream& operator<<(std::ostream&, const Math::Matrix&);
请注意,操作者过载的命名空间之外声明。
<强> Matrix.cpp 强>
using namespace Math;
using namespace std;
ostream& operator<< (ostream& os, const Matrix& obj) {
os << obj.getXYZ() << obj.getABC() << '\n';
return os;
}
在另一方面,如果你的过载功能的不的需要作出的一个朋友,即需要private和protected成员访问。
<强> MATH.H 强>
namespace Math {
class Matrix {
public:
friend std::ostream& operator<<(std::ostream&, const Matrix&);
};
}
您需要与命名空间块而不是仅仅using namespace Math;
以包围函数定义。
<强> Matrix.cpp 强>
using namespace Math;
using namespace std;
namespace Math {
ostream& operator<<(ostream& os, const Matrix& obj) {
os << obj.XYZ << obj.ABC << '\n';
return os;
}
}
在C ++ 14可以使用下面的模板来打印其具有T ::打印(标准:: ostream的&)const的任何物体;构件。
template<class T>
auto operator<<(std::ostream& os, const T& t) -> decltype(t.print(os), os)
{
t.print(os);
return os;
}