문제

매트릭스 작업을 위해 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; 
} 
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top