C++ 연산자 오버로딩 실전 가이드: 문법, 접근법, 코드 예제
연산자 오버로딩이란?
C++에서 연산자 오버로딩을 사용하면 동일한 범위 내에서 연산자에게 여러 의미를 부여할 수 있습니다. 목표는 사용자 정의 타입에 대해 연산자에게 맞춤 동작을 부여하는 것입니다.
연산자 오버로딩으로 대부분의 C++ 연산자를 재정의하고 단일 기호로 다른 연산을 수행할 수 있습니다.
이 튜토리얼에서 배울 내용:
- 연산자 오버로딩이란 무엇인가
- 문법
- C++에서 연산자 오버로딩의 다양한 접근법
- 오버로딩할 수 없는 연산자들
- 핵심 고려사항
- 연산자 오버로딩 규칙
- 실제로 연산자 오버로딩하는 방법
문법
C++ 연산자를 오버로드하려면 클래스 내부에 특수 멤버 함수를 다음과 같이 정의합니다:
class class_name {
...
public:
return_type operator symbol (argument(s)) {
...
}
...
};
구성 요소:
- return_type – 연산자 함수가 반환하는 타입
- operator – 선언을 시작하는 키워드
- symbol – 오버로드할 연산자, 예:
+, -, <, ++
- argument(s) – 다른 함수처럼 매개변수
예제 1:
#include <iostream>
using namespace std;
class TestClass {
private:
int count;
public:
TestClass() : count(5) {}
void operator --() {
count = count - 3;
}
void Display() {
cout << "Count: " << count;
}
};
int main() {
TestClass tc;
--tc;
tc.Display();
return 0;
}
출력:

코드 스크린샷:

코드 설명:
- 입출력 시설을 위해
<iostream> 포함
- 간결성을 위해
std 네임스페이스 사용
TestClass 클래스 정의
count를 private 데이터 멤버로 지정
count를 5로 초기화하는 public 생성자 제공
- 전위
-- 연산자 오버로드하여 count에서 3 감소
- 현재 값 출력용
Display() 구현
main()에서 인스턴스 생성, 오버로드된 연산자 적용, 결과 표시
C++에서 연산자 오버로딩의 다양한 접근법
오버로딩은 다음을 통해 달성 가능:
- 멤버 함수
- 비멤버 함수 (프렌드 또는 자유 함수)
- 프렌드 함수 (private 데이터 접근 필요 시)
- 왼쪽 피연산자가 클래스 객체이면 보통 멤버 함수 사용
- 왼쪽 피연산자가 다른 타입이면 비멤버 함수 필요
- 연산자가 private/protected 멤버에 접근해야 할 때 프렌드 함수 유용
모든 C++ 연산자를 오버로드할 수 있는가?
아닙니다. 다음 연산자들은 오버로드할 수 없습니다:
:: – 범위 해결
?: – 삼항 조건
. – 멤버 접근
sizeof – 크기 조회
* (멤버 포인터 선택자)
기억할 사항
- 오버로딩은 사용자 정의 타입만 영향; 내장 타입은 원래 동작 유지
- 대입(
=)과 주소-연산자(&)는 복사 생성자나 대입 연산자 제공 클래스에 자동 오버로드
- 연산자 우선순위는 변경되지 않음; 괄호로 평가 순서 강제 가능
- 세 연산자
::, ., ?:는 명시적으로 오버로딩 금지
연산자 오버로딩 규칙
- 최소 한 피연산자는 사용자 정의 클래스 타입이어야 함
- 기존 연산자만 오버로드 가능; 새 연산자 기호 도입 불가
- 일부 연산자(예:
new, delete)는 프렌드 함수로 오버로드 불가하지만 멤버 함수로는 가능
연산자 오버로딩 방법
예제 1: 증가 연산자
#include <iostream>
using namespace std;
class OperatorOverload {
private:
int x;
public:
OperatorOverload() : x(10) {}
void operator ++() {
x += 2;
}
void Print() {
cout << "The Count is: " << x;
}
};
int main() {
OperatorOverload ov;
++ov;
ov.Print();
return 0;
}
출력:

코드 스크린샷:

코드 설명:
<iostream> 포함 및 std 네임스페이스 사용
- private
int x를 가진 OperatorOverload 클래스 정의
- 생성자에서
x를 10으로 초기화
- 전위
++ 연산자 오버로드하여 x에 2 더하기
- 업데이트된 값 표시용
Print() 구현
main()에서 객체 생성, 오버로드된 연산자 호출, 결과 출력
예제 2: 복소수 덧셈
#include <iostream>
using namespace std;
class TestClass {
private:
int real, over;
public:
TestClass(int rl = 0, int ov = 0) : real(rl), over(ov) {}
TestClass operator + (TestClass const &obj) {
TestClass result;
result.real = real + obj.real;
result.over = over + obj.over;
return result;
}
void print() {
cout << real << " + i" << over << endl;
}
};
int main() {
TestClass c1(9, 5), c2(4, 3);
TestClass c3 = c1 + c2;
c3.print();
}
출력:

코드 스크린샷:

코드 설명:
<iostream> 포함 및 std 네임스페이스 사용
real과 over 컴포넌트를 가진 TestClass 정의
- 초기화용 생성자 제공
+ 연산자 오버로드로 복소수 덧셈 수행
- 합을 담은 새
TestClass 인스턴스 반환
- 복소수 표시용
print() 구현
main()에서 두 인스턴스 생성, 덧셈, 결과 출력
요약
- 연산자 오버로딩은 범위 내에서 연산자에게 여러 의미 부여 가능
- 사용자 정의 타입에 맞춤 동작 제공
- 대부분 C++ 연산자 오버로드 가능하지만 일부는 불가
- 최소 한 피연산자는 사용자 정의 타입이어야 함
- 기존 연산자만 오버로드 가능