2012-02-27 17 views
2

내가 클래스 마지막 학기 오래된 HW 과제를 통해 진행되고 근래. 이것은 연결된 목록 개체를 인쇄하는 지정된 인쇄 기능입니다. 오버로드 된 연산자가 두 개의 매개 변수를 취하는 이유와 하나가 os 개체 인 이유를 이해할 수 없습니다. main.cpp에 실제 연결된리스트 객체를 출력 할 때, 우리는 객체를 전달할 필요가 없었습니다. 또한 왜 OS를 반환합니까? 왜 우리는 대신 "OS < <"의 cout을 사용할 수 없습니다?오버로드 연산자 << ostream에 구문

감사합니다.

template <class T> 
void List<T>::print(ostream & os) const 
{ 
    os << "<"; 
    ListNode * curr = head; 
    while (curr != NULL) { 
     os << " " << curr->data; 
     curr = curr->next; 
    } 
    os << " >"; 
} 



// overloaded operator<< 
template <class T> 
ostream & operator<<(ostream & os, const List<T> & list) 
{ 
    list.print(os); 
    return os; 
} 

답변

6

질문을 묻는 방법과 기본 원리는 매우 단순하지만 (다소 비공식적이고 너무 평범하지는 않지만) 대답하려고 노력할 것입니다. 오버로드 된 연산자

운영자 < <는 이항 연산자 인 운영 체제 객체에게있는 두 개의 매개 변수 하나 걸리는 이유

는 이해가 안 돼요. 그것에는 왼쪽과 오른쪽이 있습니다. 당신은 쓸 때 :

cout << 123; 

당신은 두 개의 피연산자 (인수)로이 연산자를 호출 할 'cout을'을 왼쪽과 정수, '123'에, 오른쪽에.

우리는 main.cpp에서 실제 연결된 목록 개체를 인쇄 할 때 은 os 개체를 전달하지 않아도됩니다.

인쇄 기능은 클래스의 구성원 기능 또는 운영자입니다. 이것은 암묵적으로, 당신의리스트 객체를 다루기위한 'this'포인터가 이미 있기 때문에, 명시 적으로 말하면서, 첫 번째 인자가 명시 적으로 전달 될 필요가 없다는 것을 암시합니다. 멤버가 아닌 연산자의 경우에는 왼쪽 피연산자에 대해 이미 작동하는 암시 적으로 추론 된 'this'객체가 없으므로 그렇지 않습니다.

당신은 다음과 같은 코드를 작성하는 경우 :

my_list.print(cout); 

당신은 같은 실제로 두 개의 인수 '을 my_list'과 'cout을'전달 생각할 수 있습니다. 명시 적으로 작성하지 않더라도 멤버와 함께 'this'를 통해 'my_list'에 액세스 할 수 있습니다. 당신과 같이, 비 구성원으로 인쇄 기능을 작성하는 경우 그 그렇지 않다 :

또한 멤버 함수 아닌 운영자의 경우입니다
template <class T> 
void print(const List<T>& my_list, ostream& os); 

.

또한

, 왜 OS를 반환?

cout << "hello " << "world"; 

먼저 우리는 운영자가 < < (cout을, "안녕하세요")를 우리에게 또 다른 ostream에 참조를 제공하는 작업을 호출 : ostream에 대한 참조를 반환

우리가이 같은 문장을 쓸 수 있습니다 것입니다 그러면 우리는 연산자 < < (cout, "world")을 호출 할 수 있습니다. 예를 들어 그것이 void를 반환하면 왼쪽 피연산자로 void를 사용하여 "world"를 출력하려고하기 때문에 하나의 명령문에서 해당 연산자를 두 번 호출 할 수 없습니다.

"os < <"대신 "cout"을 사용할 수없는 이유는 무엇입니까?

cout은 기본적으로 ostream 인터페이스를 구현합니다. ofstream, ostringstream 및 기타 유형의 출력 스트림도 마찬가지입니다. 기본적으로 인터페이스 인이 필요하며 일부 ostream 파생물은 필요하지 않으므로 작성하면 stdio 스트림, 파일 스트림, 스트림 스트림 및 기타와 함께 작동하도록 작성할 수 있습니다. 기본적으로 코드는 매우 일반적이며 재사용이 가능합니다. 이는 실용적 일 때해야 할 일입니다. 다형성의 개념을 다룰 때이 주제에 관해 더 배우게됩니다.

+0

"스트림 스트림"? 그것은 "문자열 스트림"에 대한 오타입니까? –

2

글로벌 비회원 기능이기 때문에. 멤버 함수 버전에서는 첫 번째 매개 변수가 암시 적으로 호출하는 개체 인 this입니다. 즉, 수업은 항상 왼쪽에 있어야합니다. 비 멤버 함수를 사용하면 명시적인 매개 변수입니다. 이 방법으로 원하는 유형을 지정할 수 있고 소스를 수정할 수없는 클래스에 대해 연산자를 오버로드 할 수 있습니다 (하나 이상의 매개 변수가 사용자 정의 유형 인 한).

os을 사용하는 이유는 파일 스트림과 모든 항목 (ostream에서 상속되는 모든 항목)이 cout 대신 작동하기 때문입니다.

반환 값에 대해 operator<< 호출을 더 많이 수행 할 수 있도록 os을 반환합니다. 이렇게하면 w << x << y << z과 같은 연산자 체인이 가능 해지고 operator<<(operator<<(operator<<(w, x), y), z)과 같습니다. 당신이 void 또는 뭔가를 반환 할 경우, 당신은 당신이 void의 반환 값이 아무것도 할 수 없기 때문에 w << x에서 중지해야합니다.

0

오버로드 된 연산자가 두 개의 매개 변수를 사용하고 하나가 os 객체 인 이유를 이해할 수 없습니다. main.cpp에 실제 연결된 목록 객체를 인쇄 할 때 os 객체를 전달할 필요가 없었습니다.

예 당신이 한 : 당신이 cout << x을 말할 때, 당신은 operator<<coutx을 전달하고 있습니다.

또한

, 왜 OS를 반환?

cout << x << y을 만들 수 있습니다. 이것은 cout << x의 리턴 값으로 y 삽입 즉 (cout << x) << y로서 해석된다.

"os < <"대신 "cout"을 사용할 수없는 이유는 무엇입니까? 때때로 당신은 표준 출력과 다른 스트림에 출력하고자하기 때문에

. 우리가 MAIN.CPP에 실제 연결리스트 객체를 인쇄했을 때

0

, 우리는 하는 OS 개체를 전달할 필요가 없었다.

예, 당신은 .. 뭔가 cout을가 os 출력 스트림입니다 cout << obj;, 좋아했다.

왜 os가 반환됩니까? 왜 우리는 "os < <"대신에 cout을 사용할 수 없습니까?

이 허용 체인 : cout << obj << " " << obj2;

왜 우리가 대신 "OS < <"의 cout을 사용할 수 없습니다?

그 하드 와이어 출력 스트림 것, 그래서 당신이 파일이나 다른 출력에 쓸 수 없습니다.