2010-07-16 7 views
1

저는 이것이 아주 기본적인 것임을 알고 있습니다 만, 나는이 시점까지 추측하고 있습니다.cin/cout 오버로드에 대한 간단한 질문입니다.

Foo는 문자열 클래스의 개인 상속을 가진 개체이며, 왜 내가 캐스팅했는지를 보여줍니다. 나는 그래서 만약

(프라 타의) 프라이머 C++에서 예제를 사용하는 함수와 같은 : 그래서

istream & operator>>(istream & is, Foo & f) 
{ 
     is >> (string &)f; 
     return is; 
} 

int main() 
{ 

Foo f; 


cin >> f; 

} 

, 한 번 CIN >> f는 명중, 함수가 호출되고 현재 문자열이 istream로 저장됩니다 참고. istream 객체가 반환되었고 이제는 ...? 반환 된 istream 객체의 내용 (문자열)이 이제 f 내에 자동으로 배치됩니까? 아니면 영화가 어떻게 작동하는지 이해하는 단계를 놓쳤습니까? 내가 수행하는 경우 또한

:

int x; 

cin >> f >> x; 

어떻게 암시과 같을 것이다? (cin) >> x처럼?

마지막으로, 더 간단한 한 가지. (AN ostream에의 참조를 포함)하는 기능의 경우 나는 루프의 모든 배열 항목을 통해 전달하고있는 중이 야이 :

for(int i=0;i < 5;i++) 
{ 
os << array[i] << "\n"; 
} 

ostream에 객체가 단지 자체 내에서 각 배열 항목이 혼합되어 있습니까?

+1

'Foo'란 무엇입니까? 왜 이것을 참조 문자열로 캐스팅하고 있습니까? –

+0

Foo 객체를 캐스팅해야하므로 string 클래스에서 상속 받았다는 언급을 잊어 버렸습니다. Prata의 입문서에서 예를 들어 보겠습니다. – Ilya

+1

그냥'Foo'를 제거하고 혼란을 피하는 것이 어떻습니까? – GManNickG

답변

3

오버로드 된 연산자를 정상 함수 호출로 대체하면 매우 쉽게됩니다.

operator >>(cin, f); 

지금 (cin >> f) >> xcin >> f >> x 생각 : cin >> f 단지에 변환합니다. 첫 번째 조작자가 실행하는 동안, cin 반환 때문에 실제로되고,

operator >>(operator >>(cin, f), x); 

: 실제로 이러한 int 같은

operator >>(cin, x); 

기본 데이터 타입은 일반적으로 스트림 클래스 자체에 과부하되므로, 이것은로 변환 다음과 같이 표시됩니다.

cin.operator >>(x); 

ostream - 정확히 같은 방식으로 작동합니다.

1

cin >> f을 수행하면 과부하 해결로 오버로드 된 istream >> 오버로드를 선택하고 호출합니다. 그런 다음 오버로드에서 스트림에서 string을 추출합니다.이 스트림은 istream 및 string을 사용하는 >> 오버로드를 호출합니다.

개인적으로도 std::string에서 파생되는 것이 가장 드뭅니다. 대신 composition을 사용해야합니다 : std::string 유형의 멤버 변수가 있어야합니다.

가지고있는 캐스트가 매우 혼란 스럽습니다. 이 f에서, 다음 cin 저장에서 int를 추출 cin 및 상점에서

is >> f.stringmembervariable; 

cin >> f >> x 첫째 추출 Foo : 대신 유형 std::string의 멤버 변수가 있다면, 당신은 훨씬 더 자연 구문을 사용하는 것이 추출 할 수 그것은 x에 있습니다. 그들이 전달되는 IStream을 반환의 규칙을 따르는 >> 과부하의 모든 당신이 말하는 것처럼, 효과적으로 동일하다고 가정하면

cin >> f; 
cin >> x; 

당신이 >> 과부하에서 IStream을 반환해야하는 이유는, 이렇게 추출은 이렇게 연결될 수 있습니다.

마지막 질문의 경우 루프 내에서 array[i] 유형이 무엇이든 오버로드 된 ostream << 연산자가 호출됩니다.

0

은 당신이 할 경우 :

cin >> f; 

당신은 당신의 연산자 함수가 호출됩니다 올바른지, 그리고 CIN에 있던 어떤 문자열 이제 F에 저장됩니다.

당신이 할 경우 : 정말 무슨 일

cin >> f >> x; 

는 기능은 이전과 동일라고한다는 것입니다,하지만 그것은 CIN를 반환합니다. istream 및 int에 정의 된 오버로드가 없기 때문에 cin은 정상적으로 처리됩니다.

그래서 일단 컴퓨터가 계산하는 것입니다 : 함수에 의해

cin >> f; 

를 오버로드한다. 그리고 나서 컴퓨터는 다음을 계산합니다 :

cin >> x; 

이것은 cin과 정수에 대한 정상적인 연산입니다. 다음

os << array[i]; 

가 먼저 처리됩니다, 그리고 : 점에서

os << array[i] << "\n"; 

:

같은 일이 당신의 선으로 발생

os << "\n"; 

이 처리됩니다.

기술적으로 두 경우 모두 스트림 객체가 반환되지만 반환 된 값을 사용하는 것이 없으므로 버려졌습니다. 그것은 말했다 라인과 같은 일이 될 것입니다 :

sqrt(81); 

을 컴퓨터가 값을 계산하고 그냥 무시합니다 반환 된 값을 저장 할 변수가 없기 때문에 (또는 컴파일러가 똑똑하면 완전히를 건너).

+0

"istream 및 int에 대해 정의 된 오버로드가 없습니다. 'basic_istream'의 멤버 함수입니다. –

+0

그래서 (마지막 예제에서), os 객체를 반환하면 컴파일러는 어떻게 보입니까? 위 함수가 오버로드되어 cout << passoverarray() os 개체가 반환됩니다. os 객체가 그냥 대체합니까 (cout << passoverarray()) 컴파일러는 ostream 객체를 발견하면이를 나타냅니다. – Ilya

+0

반환 값을 사용하지 않으면 단순히 무시됩니다. 그것은 이전에 보여준 sart (81)의 경우입니다. 그러나, 만약 당신이 (cout << passoverarray())와 같은 것을하고 있다면, passoverarray()의 반환 값이 무엇이든간에 << 작업이 과부하가 될지 여부를 결정할 것입니다. passoverarray()가 정수를 반환하면, 그것은 단지 cout에 표시됩니다. 귀하의 예제에서 pasoverarray()는 << 연산자가 오버로드되도록 Foo 유형의 객체를 반환해야합니다. – pcd6623

1
istream & operator>>(istream & is, Foo & f) 
{ 
     is >> (string &)f; 
     return is; 
} 

istream& operator>>(istream& is, string& f)는 (물론, basic_istream<T>&, basic_sttring<T>&가) 이미 존재합니다. 그럼 당신이 할 수있는 동안, 왜 그럴까요?CIN >> F가 히트되면

그래서, 함수가 호출되고, 지금 문자열은 문자열 (설정

상관 스트림이 istream& operator>>(istream& is, string& f) 의해 소비되는 IStream을 참조에 저장된 의 스토리지)를 사용하여 소비 된 바이트의 표현을 포함합니다.

그런 다음 istream에 대한 참조가 반환됩니다. 때문에 운영자 연관성 규칙의

int x; 
(cin >> f) >> x; 

, 그리고 "정말"입니다 :

int x; 
cin >> f >> x; 

은 동일하다 두 operator>>의이 두 다른 오버로드 된 버전은

int x; 
std::operator>>(::operator>>(cin, f), x) ; 

op>>, 즉 전역 네임 스페이스에서 istream을 취하는 Foo가 내부 버전 인 버전 이것은 istream에 대한 참조를 반환하는데, 차례로 istream과 int를 취하는 std 네임 스페이스의 첫 번째 인수가 반환됩니다.

ostream 개체가 자체 내에있는 각 배열 항목을 합성합니까?

형 배열 [N], 스트림 순서에서 ostream에 을 첨가 최 각 오브젝트는, 개행 따른다. 그래서 "compunded"는 그것을 표현하는 나쁜 방법이지만, 그렇습니다. 당연히, op<<(ostream&, const X&)이 존재해야합니다. 여기서 "X"는 배열 [n]이 무엇이든 (암시 적으로 변환 가능)입니다.

관련 문제