2010-03-16 15 views
5

개체를 인쇄 할 때 친구 교환 원 < <이 사용됩니다. 연산자에 대한 멤버 함수를 사용할 수 있습니까 < <?친구 기능이 연산자 << 구성원의 기능보다 선호되는 이유 <<

class A { 

public: 
void operator<<(ostream& i) { i<<"Member function";} 
friend ostream& operator<<(ostream& i, A& a) { i<<"operator<<"; return i;} 
}; 


int main() { 

    A a; 
    A b; 
    A c; 
    cout<<a<<b<<c<<endl; 
    a<<cout; 
    return 0; 
} 

한 점은 친구 기능이

cout<<a<<b<<c 

어떤 다른 이유처럼 사용 할 수있게한다는 것이다?

+3

정말 다른 이유가 필요합니까? –

+0

@ mmyers : 나는 단지 내가 할 수있는만큼 명확하게 이해하려고 노력한다 .... – skydoor

+1

분명히 멤버 함수가 될 수는 없지만 (Charles Bailey의 답 참조), 친구 일 필요는 없다. if 당신은 클래스의 퍼블릭 인터페이스의 관점에서 구현할 수 있습니다. – UncleBens

답변

11

이진 연산자와 같이 멤버 함수가 아닌 자유 함수를 사용해야 만합니다. 오른 쪽이 다른 매개 변수로 전달되는 멤버 함수의 경우 왼쪽이 항상 *this입니다.

출력 스트림 연산자의 경우 왼쪽은 항상 스트림 객체입니다. 따라서 표준 클래스로 스트리밍하고 스트림을 직접 쓰지 않으면 클래스의 멤버가 아닌 무료 함수를 제공해야합니다.

는 멤버 함수로 뒤로 스트림 연산자를 제공하고이처럼 스트리밍 할 수있을 것이지만 :

myObject >> std::cout; 

뿐만 아니라 당신이 지적대로, 매우 강력한 라이브러리 규칙을 위반, 체인 출력 왼쪽에서 오른쪽으로 그룹화 된 >>으로 인해 작업이 작동하지 않습니다.

편집 : 당신이 그것을 단지 스트리밍 기능이 클래스의 공용 인터페이스의 관점에서 구현 될 수없는 경우 friend 할 필요가 무료 기능을해야하는 동안 다른 사람들이 지적했다으로.

10

선택의 여지가 없습니다. 자유로운 기능이어야합니다.

그러나 반드시 friend 기능 일 필요는 없습니다. 실제로 개인 액세스 권한을 부여해야하는 경우에만 친구가되어야합니다. 예를 들어, 내가 프로그래밍 대회에 다음을 사용 :

template <class A, class B> 
std::ostream& operator<<(std::ostream& os, const std::pair<A, B>& p) 
{ 
    return os << '(' << p.first << ", " << p.second << ')'; 
} 

first으로, 친구하고 second가 공개적으로 액세스가 필요합니다.

1

예를 들어 또 다른 이유는 클래스 정의 내부에 자유 함수를 정의하는 유일한 방법이기 때문에 friend이어야합니다. 친구가 아닌 자유 기능을 원한다면 클래스 외부에서 정의해야합니다.

왜 클래스에서 정의 하시겠습니까? 때로는 모든 연산자를 함께 정의하는 것이 좋다 :

struct SomeClass { 
    // blah blah blah 
    SomeClass &operator+=(const SomeClass &rhs) { 
     // do something 
    } 
    friend SomeClass operator+(SomeClass lhs, const SomeClass &rhs) { 
     lhs += rhs; 
     return lhs; 
    } 
    // blah blah blah 
    // several pages later 
}; 

가있을 수 있습니다 사용자 친화적 조금 이상 :이 클래스 정의에 관련된 멤버 함수를 정의 물론 가정

struct SomeClass { 
    // blah blah blah 
    SomeClass &operator+=(const SomeClass &rhs) { 
     // do something 
    } 
    // blah blah blah 
    // several pages later 
}; 

SomeClass operator+(SomeClass lhs, const SomeClass &rhs) { 
    lhs += rhs; 
    return lhs; 
} 

오히려 거기에 선언하고 .cpp 파일로 정의하는 것입니다.

편집 : 실제로 생각하지 않고 + =와 +를 예로 사용했지만 과 같이 밀접한 관련 연산자가없는 operator<<에 대한 질문입니다. 그러나 operator<<이 인쇄와 관련된 하나 이상의 멤버 함수를 호출하면 정의 된 위치 근처에서 정의 할 수 있습니다.

0

수 없습니다. 하지만 친구 기능이 아니길 바란다면 무료 기능으로 만들고 공용 인터페이스라는 측면에서 구현하십시오. 예를 들면.

ostream& operator<<(ostream& os, Myclass& obj) 
{ 
    return obj.print(os); 
} 

ostream& MyClass::print(ostream& os) 
{ 
    os << val; // for example. 
    return os; 
}