| 일 | 월 | 화 | 수 | 목 | 금 | 토 | 
|---|---|---|---|---|---|---|
| 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 | 29 | 
| 30 | 
                            Tags
                            
                        
                          
                          - GPT-4
 - Machine Learning
 - supervised learning
 - gpt
 - regression
 - 해커톤
 - LLM
 - 오블완
 - 회귀
 - deep learning
 - LG
 - PCA
 - LG Aimers 4th
 - 머신러닝
 - 분류
 - 티스토리챌린지
 - AI
 - 지도학습
 - ChatGPT
 - LG Aimers
 - 딥러닝
 - Classification
 - OpenAI
 
                            Archives
                            
                        
                          
                          - Today
 
- Total
 
SYDev
C++ Chapter 10-4: cout, cin, endl 본문
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
728x90
    
    
  반응형
    
    
    
  'Programming Lang > C++' 카테고리의 다른 글
| C++ Chapter 11-2 : 배열의 인덱스 연산자 오버로딩 (0) | 2023.07.26 | 
|---|---|
| C++ Chapter 11-1 : 대입 연산자의 오버로딩 (0) | 2023.07.25 | 
| C++ Chapter 10-4 추가 내용 (버퍼, fflush 함수) (0) | 2023.07.25 | 
| C++ Chapter 10-4 추가 내용 (함수 포인터) - 미해결 (0) | 2023.07.25 | 
| C++ Chapter 10-3 : 교환법칙 문제의 해결 (0) | 2023.07.24 |