※ 제가 개인적으로 공부하는 것이라 요약하거나 책에서 빠진 내용이 있을 수 있습니다 ※
Section 1. 연산자 오버로딩이란
C++에서 제공하는 클래스 타입, 즉 사용자 정의 타입에서도 연산자를 사용할 수 있게 하는 문법이다.
// 사용자가 정의한 코드
class Point
{
...
};
int n1 = 10, n2 = 20; 같은 경우 n1 + n2는 컴파일러에 연산이 정의되어 있어서 가능하지만 Point p1 + p2를 생으로 하려면 정의되지 않아서 연산이 불가능하다. 그래서 연산자 오버로딩을 쓰면 정의되지 않은 타입도 연산이 가능하고 코드 직관성, 가독성을 올려준다.
Section 2. 연산자 오버로딩 및 정의하기
Point 클래스에서 연산자 + 정의 예제
#include <iostream>
using namespace std;
class Point
{
int x;
int y;
public:
Point(int _x = 0, int _y = 0) : x(_x), y(_y) { }
void Print() const { cout << x << ', ' << y << '\n' }
void operator+(const Point& arg)
{
Point pt;
pt.x = this->x + arg.x;
pt.y = this->y + arg.y;
}
};
int main()
{
Point p1(2, 3), p2(5, 5);
Point p3;
p3 = p1 + p2; // => p1.operator+(p2);
p3.Print(); // 7, 8 출력
p3 = p1.operator+(p2); // 직접 호출
p3.Print(); // 7, 8 출력
return 0;
}
참고로 const와 비 const 멤버 함수는 필요할 때 잘 쓰자. 이펙티브 C++ 항목 3에도 나오는데 const는 낌새가 보이면 일단 들이대라고 나온다.
Section 3. 단항 연산자 오버로딩
오버로딩이 가능한 단항 연산자는 !, &, ~, *, +, -, ++, -- 형변환 연산자이다.
++ 연산자 오버로딩 예제
#include <iostream>
using namespace std;
class Point {
private:
int x, y;
public:
Point(int x = 0, int y = 0) : x(x), y(y) {}
// 전위 증가 연산자 (++p)
Point& operator++() {
++x;
++y;
return *this; // 변경된 객체 자신을 반환
}
// 후위 증가 연산자 (p++)
Point operator++(int) {
Point temp = *this; // 현재 상태 저장
x++;
y++;
return temp; // 변경 전 상태 반환
}
void print() const {
cout << "(" << x << ", " << y << ")" << endl;
}
};
int main() {
Point p(1, 2), p2(2, 3);
Point result;
result = ++p1; // p1.operator++(); 와 같다
p1.Print(); // 3, 4
result.Print(); // 3, 4
result = p2++; // p2.operator++(0); 과 같다
p2.Print(); // 3, 4
result.Print(); // 2, 3
return 0;
}
Section 4. 이항 연산자 오버로딩
오버로딩이 가능한 이항 연산자는 +, -, *, /, ==, !=, <, <= 등이 있다.
==, != 연산자 오버로딩 예제
bool operator==(const Point& arg) const
{
return x == arg.x && y == arg.y ? true : false;
}
bool operator!=(const Point& arg) const
{
return !(*this == arg);
}
Section 5. 전역 함수를 이용한 연산자 오버로딩
연산자 오버로딩에는 두 가지가 존재
1. 멤버 함수를 이용한 Section 1~4까지의 연산자 오버로딩
2. 전역 함수를 이용한 연산자 오버로딩
이걸 p1 == p2에 빗대어보면
1번은 p1.operator == (p2); 처럼 해석
2번은 operator == (p1, p2); 처럼 해석.
2번을 써야하는 경우는 다음과 같다
Point p1(1, 2);
k + p1; // k는 연산자 오버로딩 객체가 아니므로 k.operator+(p1)처럼 호출할 수
// 없어서 operator+(k, p1)처럼 호출해야 한다.
전역 함수를 이용한 연산자 오버로딩 예제
class Point
{
...
}
const Point operator-(const Point& argL, const Point& argR)
{
return Point(argL.GetX() - argR.GetX(), argL.GetY() - argR.getY());
}
int main()
{
Point p1(2, 3), p2(5, 5);
Point p3;
p3 = p1 - p2;
p3.Print(); // -3, -2 출력
return 0;
}
p1 - p2는 전역 함수 operator-(p1,p2)를 호출한다.
참고로, private 변수인 x와 y에 직접 참고를 할 수 없으므로 GetX 같은 getter 함수를 선언한건데, 이 외에도 friend 함수를 선언하고 사용해도 되는데, 이펙티브 C++ 책에서는 "friend는 꼭 필요할 때만 사용하라고" 해서 getter가 보편적으로는 더 좋은 방법인 것 같다.
'C++ > C++ STL' 카테고리의 다른 글
C++ STL (뇌를 자극하는) - 4장. 함수 템플릿 (Section 2 ~ 3) (0) | 2025.07.28 |
---|---|
C++ STL (뇌를 자극하는) - 4장. 함수 템플릿 (Section 1) (2) | 2025.07.27 |
C++ STL (뇌를 자극하는) - 3장. 함수 객체란 (1) | 2025.07.25 |
C++ STL (뇌를 자극하는) - 2장. 함수 포인터 (2) | 2025.07.24 |
C++ STL (뇌를 자극하는) - 1장. 연산자 오버로딩 (Section 6~7) (0) | 2025.07.23 |