2011-12-04 4 views
10

내 클래스 중 하나에 연산자 < <을 오버로드하려고합니다. 서명은 다음과 같이 진행됩니다C++ - friend 함수를 헤더 파일에 정의해야합니까?

friend std::ostream& operator<<(std::ostream& os, const Annuaire& obj) 

나는 내가 .H에 정의하면, 통화 당에 정의는 운영자 < < 정확히 그러나, 1 개 인자를 말한다 파일을 시도, 그것은 컴파일/잘 작동합니다.

std::ostream& Annuaire::operator<<(std::ostream& os, const Annuaire& obj){ // ... } 

는 헤더 파일에 정의 할 필요가 친구 함수와 아무 상관이 있나요 :

이 내가 .cpp 파일에 정의하는 방법이다?

+0

당신은 ostream'와'istream' 바로 ... –

+0

그래, 친구가 IStream을하고 그것이 의도적 인 당신이이 개 친구의 선언과 2 정의가 필요합니다 경우 CPP의 하나가, ostream에있다'가야 , 그렇지 않다면, 당신이 밖으로 또는 밖으로 스트림을 원한다면 따라 하나 또는 다른 수정 –

+0

고마워, 그것은 복사 - 붙여 넣기 실수 어쨌든했다. – Pacane

답변

9

하지만 적어도 은 헤더 파일에 선언 할 필요가 :이 같은이어야한다 과부하가 아닌 스트림 자체가주는 물건을 확인하십시오.

// .h and in class 
friend std::ostream& operator<<(std::ostream& os, MyClass const& v); 

// .cpp 
std::ostream& operator<<(std::ostream& os, MyClass const& v){ 
    // print it 
} 
2

해당 제한 없음; 당신은 아마 그것을 잘못 쓰고있을 것입니다. 당신이 그것을 사용하려는 경우에만 것이다, 그렇지 않으면 모든 장소, 그것은 는 CPP 파일에을 정의 할 수 있습니다

class Foo 
{ 
    int n; 

    friend std::ostream & operator<<(std::ostream &, Foo const &); 
}; 

std::ostream & operator<<(std::ostream & o, Foo const & x) 
{ 
    return o << x.n; 
} 
9

문제는 정의하는 방식과 관련이 있습니다. 클래스의 구성원이 아니며, 친구 인입니다. Annuaire:: 접두어를 삭제해야합니다. 그래서,이 변경 :

std::ostream& Annuaire::operator<<(std::ostream& os, const Annuaire& obj){ // ... 

을 여기에 :

std::ostream& operator<<(std::ostream& os, const Annuaire& obj){ // ... 

오류 메시지에 대한 이유는 Annuaire::operator<<(std::ostream& os, const Annuaire& obj)는 세 개의 인수를 기대하는 것입니다 : 그것은 (this로)에라고하는 Annuaire 인스턴스를하고, 그리고 두 개의 추가 인수 (osobj).

3

친구 기능은 비록 이라도 클래스 내에서 선언 될 것으로 보이면은 멤버 함수가 아니라 (네임 스페이스의 네임 스페이스에있는) 네임 스페이스 레벨 함수입니다. 코드에서 올바르게 친구 함수를 선언,하지만 당신은 클래스의 멤버 함수로 정의하려고 : operator<<라고

std::ostream& Annuaire::operator<<(std::ostream& os, const Annuaire& obj){ 

그 정의는 Annuaire의 멤버 함수에 대한 것, 2 개 개의 인수를 취하는, 어떤 유효하지 않은 operator<< 두 가지 방법 중 하나를 오버로드 할 수 있습니다 : 두 개의 인수 (왼쪽 및 오른쪽 측면) 또는 인수를 취하는 식의 lhs에 나타나는 클래스의 멤버 함수를 사용하여 자유 함수로 오버로드 할 수 있습니다. rhs 유형. 다윗의 답변에서 언급 한 바와 같이 운영자가 아닌이 경우,

std::ostream& operator<<(std::ostream& os, const Annuaire& obj) 
+0

둘러싸는 네임 스페이스에 메모를 추가하는 경우 +1입니다. 실제 함수 정의 앞에'using namespace X'를 추가하는 것만으로는 충분하지 않습니다. – moooeeeep

2

: 좌변이 std::ostream하고 당신이 그것을 수정할 수 있기 때문에이 특별한 경우에, 당신은 무료로 기능을 사용할 수있는 유일한 옵션으로 남아 있습니다 멤버 함수가 아니라면, 그것은 같은 네임 스페이스의 친구 함수 일뿐입니다. 이것은 비슷한 문제를 푸는 올바른 방향으로 나를 지적했습니다.

나에게 즉시 명백하지 않았기 때문에이 답변을 게시하고 있습니다. 연산자를 추가하는 구현 파일이 네임 스페이스에 완전히 포함되어 있지 않아서 대신 using 지시문을 사용했기 때문일 수 있습니다.

관련성이 없어야하지만 VS2013을 사용하고 있습니다.

//Foo.h 
namespace Bar{ 
    class Foo 
    { 
    public: 
     Foo(); 
    private: 
     int n; 
     friend std::ostream & operator<<(std::ostream &, Foo const &); 
    }; 
} 

//Foo.cpp 
using namespace Bar; //won't apply to the operator definition 
Foo::Foo(){}// doesn't require the Bar qualifier because of the using-directive 

//the operator required the Bar namespace qualifier 
std::ostream & Bar::operator<<(std::ostream & o, Foo const & x) 
{ 
    return o << x.n; 
} 
+0

정확히 내 문제! 나는 왜 이것이 일어나고 있는지 너무 확신하지 못한다. – Flynsee

관련 문제