Notice
Recent Posts
Recent Comments
«   2025/02   »
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28
Archives
Today
Total
관리 메뉴

SYDev

C++ Chapter 10-4: cout, cin, endl 본문

Programming Lang/C++

C++ Chapter 10-4: cout, cin, endl

시데브 2023. 7. 25. 18:24

cout, endl의 이해

 cout와 endl의 이해를 위해 예제 하나를 살펴보자.

#include <iostream>
namespace mystd
{
    using namespace std;    //printf 함수의 호출을 위해 선언

    class ostream
    {
    public:
        void operator<< (char * str)
        {
            printf("%s", str);
        }
        void operator<< (char str)
        {
            printf("%c", str);
        }
        void operator<< (int num)
        {
            printf("%d", num);
        }
        void operator<< (double e)
        {
            printf("%g", e);
        }
        void operator<< (ostream& (*fp)(ostream &ostm)) //함수 포인터의 선언: 함수의 반환형 (*함수 포인터의 이름)(매개변수)
        {
            fp(*this);
        }
    };

    ostream& endl(ostream &ostm)
    {
        ostm<<'\n';
        fflush(stdout); //출력 버퍼에 있는 데이터를 비우는 즉시 출력
        return ostm;
    }

    ostream cout;   //cout는 객체 이름
}

int main(void)
{
    using mystd::cout;
    using mystd::endl;

    cout<<"Simple string";
    cout<<endl;
    cout<<3.14;
    cout<<endl;
    cout<<123;
    endl(cout);

    return 0;
}
Simple string
3.14
123

 cout<<endl; 이 문장을 자세히 풀어서 보면 다음과 같다.

cout<<endl;
cout.operator<<(endl);	
/*
ostream& (*fp)(ostream &ostm) = endl; 
-> fp = endl; 
-> 함수 내부에서 endl(*this)
-> 입력 버퍼가 비워지고 입력 버퍼에 저장된 \n이 출력
*/

 추가적으로 위 예제에서는 <<연산을 연속적으로 다음과 같이 실행할 수 없다.

cout<<123<<endl<<3.14<<endl;	//((cout.operator<<(123)).operator<<(endl)).operator<< ....

 위와 같은 형태로 실행되려면 operator<< 연산의 결과로 cout를 반환해야 한다.

 

 해당 내용을 참고해 예제를 확장해보자.

#include <iostream>
namespace mystd
{
    using namespace std;    

    class ostream
    {
    public:
        ostream& operator<< (char * str)
        {
            printf("%s", str);
            return *this;
        }
        ostream& operator<< (char str)
        {
            printf("%c", str);
            return *this;
        }
        ostream& operator<< (int num)
        {
            printf("%d", num);
            return *this;
        }
        ostream& operator<< (double e)
        {
            printf("%g", e);
            return *this;
        }
        ostream& operator<< (ostream& (*fp)(ostream &ostm)) 
        {
            return fp(*this);
        }
    };

    ostream& endl(ostream &ostm)
    {
        ostm<<'\n';
        fflush(stdout); 
        return ostm;
    }

    ostream cout;  
}

int main(void)
{
    using mystd::cout;
    using mystd::endl;

    cout<<3.14<<endl<<123<<endl;

    return 0;
}
3.14
123

 

<<, >> 연산자의 오버로딩

<< 연산자의 오버로딩

 이번에는 앞서 정의한 Point 클래스를 대상으로 <<연산자와 >>연산자를 오버로딩해보자.

  • cout는 ostream 클래스의 객체이다.
  • ostream은 이름공간 std안에 선언되어 있으며, 이의 사용을 위해서는 헤더파일 <iostream>을 포함해야 한다.

 그렇다면 cout<<pos를 구현하기 위해서 멤버함수와 전역함수 중 어떤 형태로 오버로딩을 진행할지 정해야 한다.

  • 멤버함수: cout.operator<<(pos)       ->       ostream 클래스 내부에 멤버 함수를 추가해야 한다.
  • 전역함수: operator<(cout, pos)        ->       따로 클래스의 수정 없이 가능하다.

 우리가 ostream 클래스를 수정하는 것은 불가능하므로, 전역함수의 형태를 선택하는 것이 합리적으로 보인다.

 

 최종적으로 확장된 예제를 살펴보자.

#include <iostream>
using namespace std;

class Point
{
private:
    int xpos, ypos;
public:
    Point(int x=0, int y=0) : xpos(x), ypos(y)
    { }
    void ShowPosition() const
    {
        cout<<'['<<xpos<<", "<<ypos<<']'<<endl;
    }
    friend ostream& operator<<(ostream&, const Point&);
};

ostream& operator<<(ostream& os, const Point& pos)
{
    os<<'['<<pos.xpos<<", "<<pos.ypos<<']'<<endl;
    return os;
}

int main(void)
{
    Point pos1(1, 3);
    cout<<pos1;
    Point pos2(101, 303);
    cout<<pos2;
    
    return 0;
}
[1, 3]
[101, 303]

 

>>연산자의 오버로딩

  • cin은 istream 클래스의 객체이다.
  • istream은 이름공간 std 안에 선언되어 있으며, 이의 사용을 위해서는 헤더파일 <iostream>을 포함해야 한다.
#include <iostream>
using namespace std;

class Point
{
private:
    int xpos, ypos;
public:
    Point(int x=0, int y=0) : xpos(x), ypos(y)
    { }
    void ShowPosition() const
    {
        cout<<'['<<xpos<<", "<<ypos<<']'<<endl;
    }
    friend ostream& operator<<(ostream&, const Point&);
    friend istream& operator>>(istream&, const Point&);
};

ostream& operator<<(ostream& os, const Point& pos)
{
    os<<'['<<pos.xpos<<", "<<pos.ypos<<']'<<endl;
    return os;
}

istream& operator>>(istream& is, const Point& pos)
{
    is>>pos.xpos>>pos.ypos;
    return is;
}

int main(void)
{
    Point pos1;
    cout<<"x, y 좌표 순으로 입력: ";
    cin>>pos1;
    cout<<pos1;

    Point pos2;
    cout<<"x, y 좌표 순으로 입력: ";
    cin>>pos2;
    cout<<pos2;
    
    return 0;
}
x, y 좌표 순으로 입력: 3 7
[3, 7]
x, y 좌표 순으로 입력: 4 9
[4, 9]

 


출처 : 윤성우, <윤성우의 열혈 C++ 프로그래밍>, 오렌지미디어, 2010.05.12