ostream에 << 연산자를 올바르게 오버로드하는 방법은 무엇입니까?
행렬 작업을 위해 C ++로 작은 행렬 라이브러리를 작성하고 있습니다. 그러나 내 컴파일러는 전에는 그렇지 않은 곳에서 불평합니다. 이 코드는 6 개월 동안 선반에 있었고 컴퓨터를 데비안 에칭에서 레니 (g ++ (Debian 4.3.2-1.1) 4.3.2)로 업그레이드했지만 동일한 g ++의 우분투 시스템에서 동일한 문제가 있습니다. .
내 매트릭스 클래스의 관련 부분은 다음과 같습니다.
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
의 범위 내에 정의가 표시 되더라도 주변 네임 스페이스를 자동으로 대상으로 지정 하지만 인수 종속 조회로 해당 연산자 정의를 찾도록하는 Matrix 객체로 operator <<를 호출하지 않으면 표시되지 않습니다. 모호한 호출에 도움이 될 수 있습니다. Matrix 이외의 인수 유형에서는 보이지 않기 때문입니다. 정의를 작성할 때 긴 접두사로 이름을 한정하고와 같은 템플릿 매개 변수를 제공하지 않고도 Matrix에 정의 된 이름과 Matrix 자체를 직접 참조 할 수도 있습니다 Math::Matrix<TypeA, N>
.
Mehrdad answer에 추가하려면
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;
}
반면에, 당신의 과부하 기능은 경우 않습니다 즉 개인 보호 멤버에 대한 액세스를 필요로하는 친구를 할 필요가있다.
Math.h
namespace Math {
class Matrix {
public:
friend std::ostream& operator<<(std::ostream&, const Matrix&);
};
}
함수 정의를 just 대신 네임 스페이스 블록으로 묶어야합니다 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;
}
참고 URL : https://stackoverflow.com/questions/476272/how-to-properly-overload-the-operator-for-an-ostream
'IT story' 카테고리의 다른 글
장기간 실행되는 Linux 프로세스의 시작 시간을 얻는 방법은 무엇입니까? (0) | 2020.04.21 |
---|---|
SSH 원격 명령이 수동으로 실행될 때 환경 변수가 더 적은 이유는 무엇입니까? (0) | 2020.04.21 |
GitHub 저장소에 파일과 폴더를 추가하려면 어떻게합니까? (0) | 2020.04.21 |
YouTube 및지도와 같은 iPhone 앱에 http + 도메인 기반 URL 체계를 등록 할 수 있습니까? (0) | 2020.04.21 |
img 태그의 src를 프로그래밍 방식으로 변경 (0) | 2020.04.21 |