C++은 객체 지향 프로그래밍 언어로, 사용자 정의 타입(클래스)을 정의할 수 있습니다. 이러한 클래스에서 연산자를 사용자 정의 타입에 맞게 동작하도록 오버로딩(overloading)할 수 있습니다. 연산자 오버로딩을 활용하면 직관적이고 간결한 코드를 작성할 수 있으며, 객체 간의 연산을 정의하거나 확장할 수 있습니다.
이 글에서는 C++의 연산자 오버로딩에 대해 설명하고, 예제를 통해 이를 구현하는 방법을 알아보겠습니다.
연산자 오버로딩이란?
연산자 오버로딩은 C++에서 제공하는 연산자를 사용자 정의 클래스에서 사용할 수 있도록 재정의하는 기능입니다. 예를 들어, +
, -
, *
, /
, ==
와 같은 연산자를 클래스의 동작에 맞게 정의할 수 있습니다.
연산자 오버로딩의 특징
- 기존 연산자의 의미 확장: 기존 연산자를 사용자 정의 타입에 맞게 동작하도록 재정의합니다.
- 가독성 향상: 연산자를 활용하여 코드의 가독성을 높일 수 있습니다.
- 멤버 함수와 비멤버 함수로 구현 가능: 연산자는 멤버 함수 또는 비멤버 함수로 구현할 수 있습니다.
주의: 연산자 오버로딩은 새로운 연산자를 생성하는 것이 아니라, 기존의 연산자를 확장하는 것입니다. 또한, C++에서 일부 연산자는 오버로딩할 수 없습니다.
오버로딩 가능한 연산자
C++에서 오버로딩 가능한 연산자는 다음과 같습니다.
- 산술 연산자:
+
,-
,*
,/
,%
- 비교 연산자:
==
,!=
,<
,>
,<=
,>=
- 논리 연산자:
&&
,||
,!
- 비트 연산자:
&
,|
,^
,~
,<<
,>>
- 기타 연산자:
[]
,()
,->
,=
등
연산자 오버로딩 구현하기
기본 구조
연산자 오버로딩은 클래스의 멤버 함수 또는 비멤버 함수로 구현됩니다. 구현 방식은 다음과 같습니다:
- 멤버 함수로 구현할 경우: 좌측 피연산자가 클래스 객체입니다.
- 비멤버 함수로 구현할 경우: 좌측 피연산자가 클래스 객체가 아닌 경우에도 동작 가능합니다.
예제: 복소수 클래스에 +
연산자 오버로딩하기
다음은 복소수(Complex Number) 클래스를 정의하고, +
연산자를 오버로딩하여 두 복소수를 더하는 예제입니다.
#include <iostream>
class Complex {
private:
double real;
double imag;
public:
// 생성자
Complex(double r = 0.0, double i = 0.0) : real(r), imag(i) {}
// + 연산자 오버로딩 (멤버 함수)
Complex operator+(const Complex& other) const {
return Complex(real + other.real, imag + other.imag);
}
// 출력용 함수
void display() const {
std::cout << "(" << real << ", " << imag << ")" << std::endl;
}
};
int main() {
Complex c1(1.0, 2.0);
Complex c2(3.0, 4.0);
Complex c3 = c1 + c2; // + 연산자 사용
std::cout << "c1: ";
c1.display();
std::cout << "c2: ";
c2.display();
std::cout << "c3 (c1 + c2): ";
c3.display();
return 0;
}
출력 결과
c1: (1, 2)
c2: (3, 4)
c3 (c1 + c2): (4, 6)
예제: 비교 연산자 오버로딩 (==
)
다음은 두 복소수가 같은지 비교하기 위해 ==
연산자를 오버로딩하는 예제입니다.
#include <iostream>
class Complex {
private:
double real;
double imag;
public:
Complex(double r = 0.0, double i = 0.0) : real(r), imag(i) {}
// == 연산자 오버로딩
bool operator==(const Complex& other) const {
return (real == other.real) && (imag == other.imag);
}
};
int main() {
Complex c1(1.0, 2.0);
Complex c2(1.0, 2.0);
Complex c3(3.0, 4.0);
std::cout << std::boolalpha; // bool 값을 true/false로 출력
std::cout << "c1 == c2: " << (c1 == c2) << std::endl;
std::cout << "c1 == c3: " << (c1 == c3) << std::endl;
return 0;
}
출력 결과
c1 == c2: true
c1 == c3: false
연산자 오버로딩의 규칙
- 기존 연산자의 우선순위는 변경할 수 없습니다.
- 연산자의 기본 의미를 유지해야 합니다. 예를 들어,
+
는 더하기 동작을 나타내야 합니다. - 적절한 반환값을 사용해야 합니다. 예를 들어, 비교 연산자는
bool
값을 반환해야 합니다.
오버로딩하지 못하는 연산자
다음 연산자는 C++에서 오버로딩할 수 없습니다:
::
(범위 지정 연산자).
(멤버 접근 연산자).*
(멤버 포인터 연산자)sizeof
(크기 연산자)typeid
(타입 정보 연산자)
마치며
연산자 오버로딩은 객체 지향 프로그래밍의 강력한 기능 중 하나로, 사용자 정의 타입을 더욱 직관적이고 자연스럽게 사용할 수 있도록 합니다. 위 예제를 참고하여 다양한 연산자를 오버로딩해 보세요. 연산자 오버로딩을 올바르게 사용하면 코드의 가독성과 유지 보수성을 크게 향상시킬 수 있습니다.
'cpp' 카테고리의 다른 글
C++ 템플릿 - 제네릭 프로그래밍 (0) | 2024.12.20 |
---|---|
C++ 네임스페이스(namespace) (0) | 2024.12.20 |
C++ 상속과 다형성 (0) | 2024.12.19 |
C++ 클래스와 객체 (0) | 2024.12.19 |
C++ 동적 메모리 관리 (0) | 2024.12.19 |