Computer >> 컴퓨터 >  >> 프로그래밍 >> C++

C++ 스트림 삽입(<<) 및 추출(>>) 연산자 오버로딩 완벽 가이드

C++는 스트림 추출 연산자(>>)와 스트림 삽입 연산자(<<)를 사용해 int, double 같은 기본 데이터 타입을 손쉽게 입력하고 출력할 수 있습니다. 흥미로운 점은 이 두 연산자를 오버로딩하면 객체처럼 사용자가 직접 정의한 타입(user-defined type)에 대해서도 동일한 방식으로 입출력을 수행할 수 있다는 것입니다.

여기서 중요한 포인트가 하나 있습니다. 연산자 오버로딩 함수는 반드시 클래스의 friend로 선언해야 합니다. 그 이유는 이 함수가 객체를 생성하지 않은 상태에서도 호출될 수 있어야 하기 때문입니다. 실제로 cout << D1;처럼 호출할 때 왼쪽 피연산자는 ostream 객체이므로, 클래스의 멤버 함수가 아닌 외부 함수 형태로 정의하는 것이 자연스럽습니다.

다음 예제를 통해 추출 연산자(>>)와 삽입 연산자(<<)의 오버로딩 방법을 자세히 살펴보겠습니다.

예제 코드

#include <iostream>
using namespace std;
class Distance {
    private:
    int feet; // 0 to infinite
    int inches; // 0 to 12
    public:
    // required constructors
    Distance() {
        feet = 0;
        inches = 0;
    }
    Distance(int f, int i) {
        feet = f;
        inches = i;
    }
    friend ostream &operator<<( ostream &output, const Distance &D ) {
        output << "F : " << D.feet << " I : " << D.inches;
        return output;
    }
    friend istream &operator>>( istream &input, Distance &D ) {
        input >> D.feet >> D.inches;
        return input;
    }
};
int main() {
    Distance D1(11, 10), D2(5, 11), D3;
    cout << "Enter the value of object : " << endl;
    cin >> D3;
    cout << "First Distance : " << D1 << endl;
    cout << "Second Distance :" << D2 << endl;
    cout << "Third Distance :" << D3 << endl;
    return 0;
}

실행 결과

$./a.out
Enter the value of object :
70
10
First Distance : F : 11 I : 10
Second Distance :F : 5 I : 11
Third Distance :F : 70 I : 10

코드 설명

Distance 클래스 구조

Distance 클래스는 피트(feet)와 인치(inches)를 나타내는 두 개의 private 멤버 변수를 가지며, 기본 생성자와 매개변수가 있는 생성자를 함께 제공합니다.

삽입 연산자(<<) 오버로딩

operator<< 함수는 ostream& 타입의 참조를 반환하며, 객체의 feetinches 값을 원하는 형식으로 출력합니다. 두 번째 매개변수가 const Distance&로 선언되어 있어 출력 과정에서 원본 객체가 수정되지 않음을 보장합니다.

추출 연산자(>>) 오버로딩

operator>> 함수는 istream& 타입의 참조를 반환하며, 사용자로부터 입력받은 값을 객체의 멤버 변수에 저장합니다.

핵심 포인트 정리

  • 연산자 함수를 friend로 선언하면 클래스 외부 함수임에도 private 멤버 변수에 직접 접근할 수 있습니다.
  • 반환 타입이 ostream& 또는 istream&이기 때문에 cout << D1 << endl;처럼 연산자를 연속으로 체이닝(chaining)할 수 있습니다.
  • 출력용 연산자에는 const 참조를 사용해 객체의 불변성을 유지하는 것이 좋은 습관입니다.

이처럼 스트림 연산자를 오버로딩하면 사용자 정의 타입도 기본 타입과 똑같이 cincout으로 자연스럽게 다룰 수 있어, 코드의 가독성과 일관성이 크게 향상됩니다.