[디딤돌 C++] 53. iostream 흉내내기

이번에는 cin과 cout으로 출력 및 입력할 때 쉬프트 연산을 사용하는 원리를 살펴보기 위해 iostream 클래스를 흉내내 보기로 할게요.

여기에서 설명하는 것은 원리를 살펴보기 위한 것이지 iostream 클래스의 내부를 정확하게 표현하기 위한 것이 아닙니다. 실제 iostream 클래스는 여기에서 설명하는 것보다 훨씬 정교하고 신뢰성있게 정의하고 있어요.

C언어에서 printf 함수로 출력하거나 scanf 함수로 입력받을 때는 포멧 사용자를 사용했었죠. 하지만 C++에서 cin과 cout을 사용할 때는 포멧 사용자 없이 쉬프트 연산을 사용했어요. 어떠한 포멧으로 출력 혹은 입력해야 하는지 표현하지 않아도 알아서 입출력해 주었죠.

이러한 것이 가능한 이유는 클래스에 연산자 중복 정의를 해 주었기 때문이예요.

class LikeAsiostream
{
public:    
    LikeAsiostream &operator<<(char value);
    LikeAsiostream &operator<<(int value);
    LikeAsiostream &operator<<(float value);
    LikeAsiostream &operator<<(double value);
    LikeAsiostream &operator<<(const void *value);
    LikeAsiostream &operator<<(const char *value);

    LikeAsiostream &operator>>(char &value);
    LikeAsiostream &operator>>(int &value);
    LikeAsiostream &operator>>(float &value);
    LikeAsiostream &operator>>(double &value);    
    LikeAsiostream &operator>>(char *value);
};

#define lendl "\n"
extern LikeAsiostream ein,eout;

그리고 각 메서드에서는 원하는 목적에 맞게 입출력 작업을 수행하게 구현합니다.

#include "LikeAsiostream.h"
#include <stdio.h>
#pragma warning(disable:4996)
LikeAsiostream ein;
LikeAsiostream eout;

LikeAsiostream &LikeAsiostream::operator<<(char value)
{
    printf("%c",value);
    return (*this);
}
LikeAsiostream &LikeAsiostream::operator<<(int value)
{
    printf("%d",value);
    return (*this);
}
LikeAsiostream &LikeAsiostream::operator<<(float value)
{
    printf("%f",value);
    return (*this);
}
LikeAsiostream &LikeAsiostream::operator<<(double value)
{
    printf("%f",value);
    return (*this);
}
LikeAsiostream &LikeAsiostream::operator<<(const void *value)
{
    printf("%p",value);
    return (*this);
}
LikeAsiostream &LikeAsiostream::operator<<(const char *value)
{
    printf("%s",value);
    return (*this);
}
                        
LikeAsiostream &LikeAsiostream::operator>>(char &value)
{
    scanf("%c",&value);
    return (*this);
}
LikeAsiostream &LikeAsiostream::operator>>(int &value)
{
    scanf("%d",&value);
    return (*this);
}
LikeAsiostream &LikeAsiostream::operator>>(float &value)
{
    scanf("%f",&value);
    return (*this);
}
LikeAsiostream &LikeAsiostream::operator>>(double &value)
{
    scanf("%lf",&value);
    return (*this);
}
LikeAsiostream &LikeAsiostream::operator>>(char *value)
{
    scanf("%s",value);
    return (*this);
}

다음은 iostream 클래스를 흉내낸 LikeAsiostream 클래스와 ein과 eout, lendl을 이용하는 예제 코드입니다.

//LikeAsiostream.h
#pragma once
class LikeAsiostream
{
public:    
    LikeAsiostream &operator<<(char value);
    LikeAsiostream &operator<<(int value);
    LikeAsiostream &operator<<(float value);
    LikeAsiostream &operator<<(double value);
    LikeAsiostream &operator<<(const void *value);
    LikeAsiostream &operator<<(const char *value);

    LikeAsiostream &operator>>(char &value);
    LikeAsiostream &operator>>(int &value);
    LikeAsiostream &operator>>(float &value);
    LikeAsiostream &operator>>(double &value);    
    LikeAsiostream &operator>>(char *value);
};
#define lendl "\n"
extern LikeAsiostream ein,eout;
//LikeAsiostream.cpp
#include "LikeAsiostream.h"
#include <stdio.h>
#pragma warning(disable:4996)
LikeAsiostream ein;
LikeAsiostream eout;

LikeAsiostream &LikeAsiostream::operator<<(char value)
{
    printf("%c",value);
    return (*this);
}
LikeAsiostream &LikeAsiostream::operator<<(int value)
{
    printf("%d",value);
    return (*this);
}
LikeAsiostream &LikeAsiostream::operator<<(float value)
{
    printf("%f",value);
    return (*this);
}
LikeAsiostream &LikeAsiostream::operator<<(double value)
{
    printf("%f",value);
    return (*this);
}
LikeAsiostream &LikeAsiostream::operator<<(const void *value)
{
    printf("%p",value);
    return (*this);
}
LikeAsiostream &LikeAsiostream::operator<<(const char *value)
{
    printf("%s",value);
    return (*this);
}
                        
LikeAsiostream &LikeAsiostream::operator>>(char &value)
{
    scanf("%c",&value);
    return (*this);
}
LikeAsiostream &LikeAsiostream::operator>>(int &value)
{
    scanf("%d",&value);
    return (*this);
}
LikeAsiostream &LikeAsiostream::operator>>(float &value)
{
    scanf("%f",&value);
    return (*this);
}
LikeAsiostream &LikeAsiostream::operator>>(double &value)
{
    scanf("%lf",&value);
    return (*this);
}
LikeAsiostream &LikeAsiostream::operator>>(char *value)
{
    scanf("%s",value);
    return (*this);
}

//Program.cpp
#include "LikeAsiostream.h"

int main()
{
    eout<<"번호:";
    int num;
    ein>>num;
    eout<<"이름:";
    char name[100];
    ein>>name;
    
    eout<<"번호:"<<num<<" 이름:"<<name<<lendl;
    return 0;
}

▷ 실행 결과

번호:45

이름:홍길동

번호:45 이름:홍길동