2012-12-10 5 views
4

I는C++에서 두 객체 모두에 과부하 연산자 <<가 발생하면 어떻게됩니까? << a는 b를

cout << "Hello world" 

cout 객체가 너무 오버 연산자를 가지고 우리가 stringscout으로 객체 멤버 함수를 전달할 수 있다고 생각했다.

그러나 일부 예제 코드에서는 연산자 오버로딩이 정의 된 클래스를 보았습니다. 그렇지 않은 경우에도

class GenericPlayer : public Hand 
{ 
    .. 
    friend ostream& operator <<(ostream& os, const GenericPlayer& aGenericPlayer); 
    .. 
}; 

... 
cout << aGenericPlayer << endl; 
... 

, 만약에 모두 coutaGenericPlayer 과부하 operator<<?

+2

'cout'과'GenericPlayer' 둘 다 삽입 연산자를 정의했는지 묻습니다 <<')를'GenericPlayer'에 사용합니까? – GManNickG

+3

'operator << '의 둘 이상의 정의가 주어진 피연산자와 일치하면 C++ 03 §13.3'[over.match]'에 나와있는 복잡한 과부하 해결 규칙에 따라 "최상"일치가 선택됩니다. "가장"일치하는 것이 고유하지 않거나 존재하지 않으면 오류입니다. –

답변

8

비록 cout과 aGenericPlayer 모두 과부하 연산자 인 경우 < <?

std::coutstd::ostream 객체, 그래서 어떤 std::ostream& operator<<(std::ostream, SomeType)std::cout 함께 작동합니다. 그러나 요점은 연산자의 두 번째 매개 변수가 다르기 때문에 과부하가 다른 것입니다. 첫 번째 "문자열"하나

std::ostream& operator<<(std::ostream&, const char*); 

두 번째

std::ostream& operator <<(std::ostream& os, const GenericPlayer& aGenericPlayer); 

그래서, 서로 다른 연산자 오버로드를하고 모호성이없는 같은 것입니다.

+0

"연산자 << (std :: ostream &, something_else)가 cout과 함께 작동 할 것입니다." –

+0

@ReubenMorais 예, 정확히 그 의미였습니다. 편집 됨. – juanchopanza

1

coutGenericPlayer 개체를 허용하려면 operator<<을 오버로드해야합니다. operator<<삽입 연산자라고도합니다. 따라서 컨텍스트에서이를 가져 오면 사용자 정의 함수의 출력을 cout에 삽입합니다. 오버로드 된 연산자는 원본 ostream 객체에 대한 참조를 반환하므로 삽입을 결합 할 수도 있습니다. 왼쪽에 ostream 개체를 인식하고 오른쪽에 GenericPlayer 개체를 인식하려면 삽입 연산자를 오버로드해야합니다. Overloading the << Operator for Your Own Classes도 참조하십시오. cout까지는 cout이 표준 출력 스트림을 나타내는 class ostream의 개체입니다. cstdio 스트림 stdout에 해당합니다. cout 수업 ostream에의 개체이기 때문에, 우리는 그 중에서도 기록 멤버 함수를 사용하여, 예를 들면 삽입 연산자를 사용하여 포맷 데이터 그것에 하나로서 문자 (ostream에 :: 연산자 < <) 또는 포맷되지 않은 데이터를 기록 할 수

+0

나는'<< '연산자가 삽입 연산자라는 사실에 동의한다. 그러나이 용어는'BigInteger operator << (BigInteger const & lhs, int rhs)'와 같은 경우에 적절할 것입니다. 인간 판독기 수준에서도 연산자 << <<가 오버로드됩니다. 삽입 또는 왼쪽으로 시프트됩니다. –

+0

@JamesKanze : ostream 연산자에 적용 할 때, 나는 관례가'삽입 '이라고 생각합니다. –

+1

동의. 그리고 대부분의 응용 프로그램에서 _only_ use입니다. 대부분의 프로그래머는 아마도 삽입을 연산자의 기본 의미로 생각할 것입니다 (역사적으로 왼쪽 시프트 연산자였습니다). –

1

들이 그것을 과부하 및 COUT aGenericPlayer 과부하 연산자 모두 < <

둘, 그것은 일반 함수 (회원)로 과부하되지 어떤 경우. 귀하의 예에서는 friend을 사용합니다. 이렇게하면 함수가 멤버가 아니더라도 클래스의 내부에 액세스 할 수 있습니다. 따라서 이러한 상황은 피할 수 있습니다.

2

우선 coutaGenericPlayer도 에 과부하가 걸리지 않습니다.그것들은 객체이고, 오버로드는 타입 에 기반합니다 (보통 타입 X가 <<, 을 오버로드하지만 <<의 오버로드가 있고 두 번째 인자로 타입 X가 일 수 있음).

두 번째로 오버로드 해상도는 모든 인수 인 에 기반합니다. ( std::cout의 종류의 기본 클래스입니다) std::istream에 대한 <<의 20여 과부하 주위에 뭔가하지만 (적어도 표준 라이브러리) 없음 번째 매개 변수로 GenericPlayer을 수 있습니다. 따라서 두 번째 피연산자가 GenericPlayer이 아닌 경우 을 사용할 수 없습니다. 마찬가지로, 가지고있는 것과 더불어 operator<<(int, GenericPlayer const&)을 가질 수 있습니다. 왼쪽 측면에 int 유형이 있고 오른쪽에 유형 GenericPlayer 유형이있는 경우 이라고합니다. (나는이 연산자가 오용 과부하가되지 않을 것이라고 생각하지 않지만, 언어는 이 허용합니다.)