타조에 대한 << 연산자에 올바르게 과부하하는 방법은 무엇입니까?
-
20-08-2019 - |
문제
매트릭스 작업을 위해 C ++로 작은 매트릭스 라이브러리를 작성하고 있습니다. 그러나 내 컴파일러는 전혀 불평하지 않았다. 이 코드는 6 개월 동안 선반에 남겨졌으며 사이에 컴퓨터가 Debian Etch에서 Lenny (G ++ (Debian 4.3.2-1.1) 4.3.2)로 업그레이드했지만 동일한 G ++의 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 & math :: matrix :: Operator << (std :: ostream &, const math :: matrix &)' '는 정확히 하나의 인수를 가져와야합니다.
나는이 오류에 약간 혼란스러워하지만, 6 개월 동안 Java를 많이 한 후 C ++가 약간 녹슬 었습니다. :-)
해결책
당신은 당신의 기능을 다음과 같이 선언했습니다 friend
. 수업의 회원이 아닙니다. 제거해야합니다 Matrix::
구현에서. friend
지정된 함수 (클래스의 구성원이 아님)가 개인 멤버 변수에 액세스 할 수 있음을 의미합니다. 기능을 구현 한 방식은 인스턴스 방법과 같습니다. Matrix
잘못된 수업.
다른 팁
다른 가능성에 대해 말씀드립니다 : 나는 그에 대한 친구 정의를 사용하는 것을 좋아합니다.
namespace Math
{
class Matrix
{
public:
[...]
friend std::ostream& operator<< (std::ostream& stream, const Matrix& matrix) {
[...]
}
};
}
함수는 주변 네임 스페이스를 자동으로 타겟팅합니다. Math
(정의가 해당 클래스의 범위 내에 나타나더라도) 그러나 연산자를 호출하지 않으면 << 매트릭스 객체를 사용하여 인수 의존적 조회가 해당 연산자 정의를 찾을 수있게하는 경우가 보이지 않습니다. 매트릭스 이외의 인수 유형에 대해 보이지 않기 때문에 때때로 모호한 전화에 도움이 될 수 있습니다. 정의를 쓸 때, 당신은 또한 긴 접두사가있는 이름을 자격이없고와 같은 템플릿 매개 변수를 제공하지 않고 매트릭스와 매트릭스 자체를 직접 참조 할 수 있습니다. Math::Matrix<TypeA, N>
.
Mehrdad 답변에 추가하려면
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;
}
반면에 과부하 기능이있는 경우 하다 친구가되어야합니다. 즉, 개인 및 보호 회원에게 접근해야합니다.
수학
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 :: print (std :: ostream &) const가있는 객체를 인쇄 할 수 있습니다. 회원.
template<class T>
auto operator<<(std::ostream& os, const T& t) -> decltype(t.print(os), os)
{
t.print(os);
return os;
}