[C++] 연산자 오버로딩 (Operator Overloading) (1)
2022. 3. 8. 13:43ㆍLanguages/C++
/* 본 글은 <씹어먹는 C++> 글을 참고하여 공부한 글입니다. */
연산자 오버로딩(Operator Overloading)
오버로딩 (Overloading)
- 객체지향언어에서 나오는 개념으로, 동일한 이름이지만 여러 개를 정의할 수 있는 것을 말한다.
- 대표적으로 함수 오버로딩이 있음
- C++에서는 연산자 또한 오버로딩을 적용할 수 있다.
- 범위지정 연산자(::), 멤버 지정 연산자(.), 멤버 포인터 지정 연산자 (.*)는 오버로딩할 수 없다.
- 기본적으로 제공되는 자료형에 적용할 때는 사용할 수 없다.
- 비정적 클래스 멤버 함수 또는 전역 함수이어야 한다.
오버로딩 가능한 연산자들
- 산술 연산자 (+, -, *, ...)
- 비교 연산자 (==, !=, ...)
- 대입 연산자 (=)
- 복합산술 연산자 (+=, -=, ..)
- 논리 연산자 (&&, ||, ..)
- 멤버 선택 연산자 (->, *(역참조))
- 증감 연산자 (++, --)
- 배열 및 함수 호출 연산자 ([ ], ( ))
연산자 오버로딩 선언 및 내부 처리
선언 형태
(리턴 타입)operator(연산자)(연산자가 받을 인자)
만약 클래스 A가 있다고 한다면, 클래스 A 객체간의 덧셈 연산자 오버로딩은 다음과 같이 적을 수 있다.
class A {
private:
int data;
public:
A(int data) : data(data) {}
A operator+(const A& a) const;
void Println() { std::cout << data << std::endl; }
};
A A::operator+(const A& a) const {
A newA(data + a.data);
return newA;
}
그러면 다음과 같이 사용하게 될 텐데,
A a1(10), a2(20);
A result = a1 + a2;
result.Println(); // 30 출력
위 문장은 사실상 컴파일러가 내부적으로 다음과 같이 변환하여 처리한다.
A a1(10), a2(20);
A result = a1.operator+(a2); // 내부적으로 처리
result.Println();
즉, 해당 객체의 연산자 함수가 호출되는 걸 볼 수 있다.
이런 방식이기 때문에 오버로딩이 가능한 게 아닌가라는 생각이 들긴 했다.
암시적 형변환을 이용한 오버로딩 방법
현재 A 클래스에는 객체와 정수 자료형 값과의 연산자가 정의되어 있지 않다. 하지만 다음 문장은 오류없이 제대로 실행된다.
A a1(10);
A result = a1 + 20;
result.Println(); // 30 출력
다시 내부적으로 처리되는 걸 적어보면 다음과 같다.
A result = a1.operator+(20);
처음에는 당연히 해당 연산자에 대한 정의가 없기 때문에 바로 실행되지는 않는다.
그래서 컴파일러는 변환을 할만한 생성자가 없는지를 살펴본다.
A(int data) : data(data) {}
즉, 아까 위의 코드는 다음과 같이 변환되어 실행된 것이다.
A result = a1.operator+(A(20));
원래라면 A operator+(int a) 이런 식의 연산자 오버로딩 또한 만들어줘야 했겠지만, 이런 방법을 이용하여 작업을 줄일 수도 있을 것 같다. 연산자 오버로딩 함수의 호출을 알았다면, 당연히 다음처럼 사용하면 오류가 발생한다.
A a1(10);
//A result = 20 + a1; 오류
728x90
반응형
'Languages > C++' 카테고리의 다른 글
[C++] 추상 클래스(abstract class) (0) | 2022.07.07 |
---|---|
[C++] 클래스 상속 시, 소멸자를 가상 함수(Virtual)로 만들어야 하는 이유 (0) | 2022.07.07 |
[C++] mutable 키워드 (0) | 2022.03.08 |
[C++] explicit 키워드 (0) | 2022.02.12 |
[C++] Const 키워드에 대해 (0) | 2022.02.09 |