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

C++ 출력 연산자(<<) 오버로드 완벽 가이드: Person 클래스 예제

C++에서 first_name(이름)과 last_name(성)이라는 두 개의 속성을 가진 Person 클래스가 있다고 가정해 보겠습니다. 이 클래스에는 이름과 성을 각각 반환하는 get_first_name() 및 get_last_name() 메서드도 함께 정의되어 있습니다. 여기에 cout 문을 사용해 객체의 이름과 성을 한 번에 출력할 수 있도록 스트림 출력 연산자(<<)를 오버로드해야 합니다.

예를 들어, 이름과 성이 각각 "Sumit"과 "Ray"인 person 객체가 입력으로 주어지면, 출력 결과는 First name – Sumit, Last name – Ray 형태가 되어야 합니다.

이 문제를 해결하기 위한 절차는 다음과 같습니다.

  • 연산자 오버로드는 반드시 클래스 외부에 정의해야 합니다.
  • 반환 타입은 ostream 참조(std::ostream&)여야 합니다.
  • 매개변수는 ostream 참조 변수 os와 출력할 객체의 참조 변수입니다.
  • os를 사용해 객체의 멤버들을 원하는 순서대로 스트림에 출력합니다.
  • 마지막에 os 객체의 참조를 반환하여 cout << p << "..."처럼 연산자 체이닝(chaining)이 가능하도록 만듭니다.

예제 코드

아래 구현 예제를 살펴보면 개념을 더 쉽게 이해할 수 있습니다.

#include <iostream>
using namespace std;
class Person {
    private:
        string f_name;
        string l_name;
    public:
        Person(string first_name, string last_name) : f_name(first_name), l_name(last_name) {}
        string& get_first_name() {
            return f_name;
        }
        string& get_last_name() {
            return l_name;
        }
};
ostream& operator<<(ostream& os, Person& p) {
    os << "First name: " << p.get_first_name() << ", Last name: " << p.get_last_name();
    return os;
}
int main(){
    Person p("Sumit", "Ray");

    cout << p << ", he is our member.";
}

입력

p("Sumit", "Ray")

출력

First name: Sumit, Last name: Ray, he is our member.

코드 설명

operator<< 함수는 클래스 외부의 전역 범위에서 정의됩니다. 왼쪽 피연산자가 ostream 객체(cout)이기 때문에 멤버 함수로 정의할 수 없으며, 비멤버 함수로 선언해야 하기 때문입니다. 함수 내부에서는 private 멤버 변수에 직접 접근하지 않고, public 게터 메서드인 get_first_name()과 get_last_name()을 호출해 데이터를 안전하게 가져옵니다.

또한 이 함수는 os 참조를 반환하기 때문에 cout << p << ", he is our member.";처럼 여러 출력 작업을 하나의 문장으로 연결해 실행할 수 있습니다. 이러한 패턴은 C++에서 사용자 정의 타입을 표준 출력 스트림과 자연스럽게 통합할 때 널리 활용됩니다.