C++ 변환 연산자란?
이 글에서는 C++의 변환 연산자(conversion operator)가 무엇인지, 그리고 실제로 어떻게 동작하는지 알아보겠습니다. C++은 객체 지향 프로그래밍을 지원하기 때문에 실제 세계의 사물들을 구체 타입(concrete type)으로 표현하는 클래스를 만들 수 있습니다.
그런데 개발을 하다 보면 특정 클래스의 객체를 다른 클래스의 객체나 int, double 같은 기본 자료형(primitive data type)으로 변환해야 하는 경우가 자주 발생합니다. 이럴 때 사용하는 것이 바로 변환 연산자입니다. 변환 연산자는 클래스 내부에 연산자 오버로딩 함수를 작성하듯이 정의하며, 기본 문법은 다음과 같습니다.
operator 대상_타입() {
// 변환된 값을 반환
}
일반 함수와 달리 반환 타입을 따로 명시하지 않고 operator 키워드 뒤에 변환하고자 하는 타입의 이름을 붙인다는 점, 그리고 매개변수를 가질 수 없다는 점이 특징입니다.
예제: 복소수 클래스를 double로 변환하기
아래 예제에서는 실수부(real)와 허수부(imaginary)를 멤버로 갖는 복소수 클래스를 만들어 보겠습니다. 이 클래스의 객체를 double 타입에 대입하거나 출력하면, 변환 연산자가 호출되어 복소수의 크기(magnitude), 즉 √(real² + imag²) 값으로 자동 변환됩니다.
예제 코드
#include <iostream>
#include <cmath>
using namespace std;
class My_Complex {
private:
double real, imag;
public:
// 기본 생성자
My_Complex(double re = 0.0, double img = 0.0) : real(re), imag(img) {}
// 크기를 구하는 일반 함수
double mag() {
return getMagnitude();
}
// 크기를 반환하는 변환 연산자
operator double() {
return getMagnitude();
}
private:
// 복소수 객체의 크기 계산
double getMagnitude() {
return sqrt(real * real + imag * imag);
}
};
int main() {
My_Complex complex(10.0, 6.0);
cout << "일반 함수를 이용한 크기: " << complex.mag() << endl;
cout << "변환 연산자를 이용한 크기: " << complex << endl;
}
실행 결과
일반 함수를 이용한 크기: 11.6619 변환 연산자를 이용한 크기: 11.6619
코드 분석
complex.mag()를 호출하면 일반 멤버 함수를 통해 크기가 계산됩니다. 반면 두 번째 출력문에서는 복소수 객체를 그대로 cout에 전달했는데, ostream에는 복소수 클래스를 위한 출력 연산자가 정의되어 있지 않습니다. 이때 컴파일러는 클래스에 정의된 operator double()을 찾아 암시적으로 호출하고, 객체를 double 값(11.6619)으로 변환한 뒤 출력합니다.
결국 변환 연산자는 객체를 마치 다른 타입의 값처럼 사용할 수 있도록 해주는 암시적 형 변환 경로를 제공하는 장치라고 할 수 있습니다.
사용 시 주의 사항
- 암시적 변환은 편리하지만, 개발자가 의도하지 않은 위치에서 조용히 호출될 수 있어 예상치 못한 버그의 원인이 될 수 있습니다.
- 이를 방지하려면 C++11부터 지원하는
explicit키워드를 변환 연산자 앞에 붙여,static_cast<double>(obj)처럼 명시적인 캐스팅이 있을 때만 변환되도록 제한하는 것이 좋습니다. - 변환 연산자는 반환 타입 선언이 없으며 매개변수를 가질 수 없다는 점도 기억해 두세요.