본문 바로가기
프로그래밍/C++

cout, cin, endl의 연산자 오버라이딩.

by Hwan2 2019. 5. 17.
반응형

흔히 C++을 시작할 때 #include로 라이브러리를 읽어 옵니다.

 

그 중 가장 먼저 접한 것이 iostream 입니다.

 

이 iostream 라이브러리 에는 class ostream이 존재 하는데, 여기에는 각 쉬프트(<<)연산자들이 오버로딩이 되어있습니다.

 

ostream& operator<<(const char *);

ostream& operator<<(char);

ostream& operator<<(short);

ostream& operator<<(int);

ostream& operator<<(long);

ostream& operator<<(float);

ostream& operator<<(double);

....

 

이런  식으로 말이죠...

 

때문에 우리는 저 함수들을 오버라이딩 해서 재정의를 할 수 있게 됩니다.

 

무슨 말이냐면.....

 

#include<iostream>

using namespace std;

class Point{
    int xpos, ypos;
public :
    Point(int x, int y) : xpos(x), ypos(y){}
};

int main(void){
    Point pos(1, 2);
    cout << pos << endl;
    return 0;
}

 

이러한 코드가 있다고 가정하고 우리는 단순 객채 전달(pos)를 통해 [1, 2] 라는 값이 출력되기를 원합니다.

 

하지만 cout에 기능에는 저희가 선언한 'Point' 라는 객체애 대한 함수 정의가 되어 있지 않음으로 원하는 출력은 불가능 합니다.

 

이를 출력하기 위해서는 2가지 방법이 있습니다.

 

첫째는 직접 iostream 라이브러리에 들어가서 ostream 클래스에다 해당 함수를 정의하는 것입니다.

 

하지만 이렇게 되버리면 ostream은 Point에 대한 클래스를 찾게 되므로 Point클래스의 정의 또한 같이 해줘야 합니다.

 

이러한 번거러움이 있을 뿐더러 비효율 적이고 이렇게 까지 하진 않습니다.

 

두번째 방법은 전역함수로 오버로딩 하는 것입니다. 

 

그냥 main함수가 있는 곳에다가 ostream을 오버라이딩 하면 되는 것입니다.

 

이것이 가능하느냐??

 

가능 합니다. 이유는, #include<iostream>으로 해당 라이브러리를 읽어오기 때문입니다.

 

이해가 안가신다면 해더 파일 선언과 파일 분할에 대해 공부하시면 됩니다.

#include<iostream>

using namespace std;

class Point{
    int xpos, ypos;
public :
    Point(int x, int y) : xpos(x), ypos(y){}

    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 pos(1, 2);
    cout << pos << endl;
    return 0;
}

 

이렇게 선언 한다면 저희가 원하는 출력 값을 얻을 수 있습니다.

 

friend를 선언한 이유는 Point의 xpos, ypos는 private으로 선언되어 있고 이를 쉽게 불러오기 위해 선언된 겁니다. 

만약 friend를 사용하기 싫타면 변수를 public으로 선언하거나 get() 함수를 따로 만들어서 호출해야 합니다.

 

그리고 참조값으로 받은 이유는 해당 데이터들은 값이 변하면 안될 뿐더러 출력 용도로만 사용하기 때문에 불필요한 메모리낭비(복사 생성자)와 

변수의 값 변경을 사전에 방지하기 위해 참조자로 선언된 것입니다. Point의 경우 const로 선언되어 있는걸 확인할 수 있습니다.

또한 ostream이 const로 선언이 되지 않았는데 ostream은 상수화가 불가능 합니다. 이유는 저도 모르겠습니다.

 

그럼 이것을 왜 굳이? 사용할까?

 

 

바로 함수 객체때문 입니다.

C++의 표준 라이브리인 STL에선 이러한 operator를 통한 함수 재정의(오버로딩, 오버라이딩)가 많이 사용됩니다.

그이유는 바로 범용성과 효율성 때문입니다.

 

사용자의 입맛에 맞춰 좀 더 효율적으로 재 정의가 가능할 뿐더러 많으 사람이 사용하기 편하게 라이브러리 형태로 만들 수 있기 때문에

C++을 공부하는 입장에서 반드시 알아야 할 개념입니다.

 

나중에 함수 객체, Lambda개념을 익힐때도 등장하며 쓰일 곳이 많습니다.

 

 

 

 

 

 

 

 

반응형

댓글


스킨편집 -> html 편집에서