2012-06-27 15 views
0

오버로드를 연습하는이 간단한 프로그램을 작성했습니다. 내가 컴파일 할 때 오류 메시지가 많이 인쇄연산자 오버로드 << C++

#include <iostream> 
#include <string> 
using namespace std; 

class sex_t 
{ 
    private: 
     char __sex__; 

    public: 
     sex_t(char sex_v = 'M'):__sex__(sex_v) 
     { 
      if (sex_v != 'M' && sex_v != 'F') 
      { 
       cerr << "Sex type error!" << sex_v << endl; 
       __sex__ = 'M'; 
      } 
     } 

     const ostream& operator << (const ostream& stream) 
     { 
      if (__sex__ == 'M') 
       cout << "Male"; 
      else 
       cout << "Female"; 
      return stream; 
     } 
}; 

int main(int argc, char *argv[]) 
{ 
    sex_t me('M'); 
    cout << me << endl; 
    return 0; 
} 

:

오류 메시지가 엉망이었다

이 내 코드입니다.

유용한 메시지를 찾지 못했습니다.

sex.cpp: 在函数‘int main(int, char**)’中: 
sex.cpp:32:10: 错误: ‘operator<<’在‘std::cout << me’中没有匹配 
sex.cpp:32:10: 附注: 备选是: 
/usr/include/c++/4.6/ostream:110:7: 附注: std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(std::basic_ostre 
+2

'cerr << "성별 오류!" << sex_v' 네 말이 맞아. 나는 그 위치에 대해 들어 본 적이 없어. – chris

+1

모든 진지하게, 반드시하지 말아야 할 것은 두 개의 밑줄을 사용하는 것입니다. 이것은 구현을 위해 예약되어 있습니다. – chris

+0

어떻게해야합니까? '_sex_' 또는 다른 것을 사용 하시겠습니까? – thlgood

답변

1

스트림에 오버로드가 발생하면 < < 연산자를 전역 적으로 및/또는 귀하의 클래스에 friend (혜택 포함)으로 액세스하여 개인 회원 (ooh ...)에 액세스 할 수 있습니다. 클래스 내에 friend을 선언하여 전역으로 선언 할 수 있습니다. 스트림에 const을 사용하지 마십시오.

다음으로 오버로드에서 전달 된 스트림을 사용하십시오. 귀하의 방법에서는 stream 인수를 사용하여 어쨌든 사용했을 때 cout을 사용합니다.

테스트하지는 않았지만 제대로 작동하는지 확인하십시오.

+0

을 거의 잊어 버렸습니까? friend'연산자 <<'또는'sex_t'에'getSex()'함수를 정의하고 있습니까? – shengy

+0

@shengy,'operator <<'는 사용자가 그것을 인쇄 할 수 있기를 기대한다면 이상적입니다. – chris

+0

@chris 친구 연산자''''또는 친구가 아닌 연산자''를 의미합니다. – shengy

4

operator<<의 인수와 리턴 값은 const가 아닙니다. 또한 비회원이어야합니다. 에 대한 과부하를 작성한 것이지 cout << me이 아닙니다. 또한 두 개의 밑줄로 이어지는 식별자는 구현을 위해 예약되어 있으며이를 사용하는 것은 정의되지 않은 동작입니다.

+0

+1; 짧고 요점. –

3

"C++ 입문 4 판"장 14 절 14.2 입력 및 출력 연산자 :

IO 운영자 비회원 기능해야하며, 우리는 연산자 우리 자신의 클래스의 멤버 수 없습니다. 우리가했던 경우, 왼쪽 피연산자는 우리의 클래스 형의 객체가 될해야합니다 :

// if operator<< is a member of Sales_item 
    Sales_item item; 
    item << cout; 

오버로드 출력 연산자의 일반적인 골격

// general skeleton of the overloaded output operator 
    ostream& 
    operator <<(ostream& os, const ClassType &object) 
    { 
     // any special logic to prepare object 

     // actual output of members 
     os << // ... 

     // return ostream object 
     return os; 
    } 

인 첫 번째 매개 변수는 참조입니다 출력이 생성 될 ostream 객체로 전달합니다. ostream은 스트림에 쓰기가 상태를 변경하기 때문에 nonconst입니다. ostream 객체를 복사 할 수 없기 때문에 매개 변수가 참조입니다.

두 번째 매개 변수는 일반적으로 인쇄 할 클래스 유형에 대한 const 참조 여야합니다. 매개 변수는 인수 복사를 피하기위한 참조입니다. 그것은 (보통) 객체를 인쇄해서 변경해서는 안되기 때문에 const 일 수 있습니다. 매개 변수를 const 참조로 만들면 단일 정의를 사용하여 const 및 nonconst 객체를 인쇄 할 수 있습니다.

반환 유형은 ostream 참조입니다. 이 값은 일반적으로 출력 연산자가 적용되는 ostream 객체입니다.

편집는 :

난 당신의 코드를 수정하려고하고 sex_t__sex__를 사용하는 경우 M '또는'F '의 개인 회원, 당신은을 얻기 위해 다른 get function를 작성해야', 그리고 경우 operator<< 함수에서 호출하면 const 참조가 const 함수 만 호출 할 수 있으므로 오류가 발생하므로 get function을 const 함수로 지정해야합니다.

+0

* const * 참조를 사용하는 또 다른 이점은 다음과 같이 할 수 있다는 것입니다 :'std :: cout << sex_t ('M');', 이는 const가 아닌 참조에 바인드 할 수 없습니다. – chris

+0

@chris 예 :) 나는 더 나은 – shengy