Channi Studies

[C++] 연산자 오버로딩 | Operator Overloading 본문

C++/기타

[C++] 연산자 오버로딩 | Operator Overloading

Chan Lee 2024. 1. 8. 23:42

연산자 오버로딩이란?

 

C++ 에서 우리는 여러가지 연산자를 사용해왔습니다.

더하기(+), 빼기(-), 나누기(/), 곱하기(*)가 대표적입니다.

 

사실 이러한 연산자들도 이미 오버로딩이 되어 있는 형태입니다.

 

오버로딩이 한 함수가 여러 다른 자료형 값을 처리할 수 있게 반복적으로 선언하는 것이였죠?

위의 일반적 연산자들도 integer, double, float 등의 자료형을 모두 다룰 수 있기 때문입니다.

 

다시 돌아와서 이러한 연산자 오버로딩을 우리가 사용하게 될 때에는,

주로 user defined type들을 built-in type들과 비슷하게 행동할 수 있게 하는 목적입니다.

 

또한 코드의 가독성을 높일 수가 있습니다.

 

이러한 연산자 오버로딩은 컴파일러에서 자동적으로 행해지지 않습니다.

한 가지 종류, 대입 연산자(=)를 제외하고는 말입니다.

 

즉, 우리가 직접 선언 및 정의를 해 주어야만 오버로딩이 됩니다.

 

 

여기서 중요한 점은, 연산자 오버로딩은 당연히 필수적이지 않습니다.

 

예를 들어, 사람의 인적사항을 보관하는 Person 클래스에 대해서 

더하기, 빼기, 나누기, 곱하기와 같은 연산자는 필요가 없을 뿐더러 이해도 잘 되지 않습니다.

 

이런 경우에는 사용하는 것이 오히려 좋지 않기 때문에, 

꼭 필요한 경우에만 사용하도록 해야 합니다.

 

 

간단한 예시를 살펴보겠습니다.

 


 

만약 우리가 Number 이라는 아무런 숫자를 담는 클래스를 다루고 있다고 해 봅시다.

 

네 숫자 a, b, c, d에 대해서 (a + b) * (c / d) 를 하고 싶다면,

다음과 같이 작성해야 할 것 입니다.

// Functions
Number result = multiply(add(a, b), divide(c, d));

// Member Methods
Number result = (a.add(b)).multiply(c.divide(d));

 

천천히 보면 이해가 되긴 하겠지만, 

가독성이 다소 떨어집니다.

 

이런 경우가 연산자 오버로딩을 하기 좋은 예시입니다.

적용 이후의 코드의 예시는 다음과 같습니다.

 

Number result = (a+b)*(c/d);

 

너무나 간단하고 읽기가 매우 편해졌습니다.

 

 

그렇다면, 어떤 종류의 연산자들이 오버로딩 가능할까요?

 


오버로딩이 가능한 연산자들

 

C++의 대부분의 연산자는 오버로딩이 가능합니다.

 

몇가지 불가능한 연산자들은 다음과 같습니다.

  • ::
  • :?
  • .*
  • .
  • sizeof

 

다시 한번 중요한 점은, 

오버로딩이 가능하다고 해서 해야된다는 것이 아닙니다.

 

코드의 가독성을 높이고 효율적으로 사용할 수 있고, 

해당 연산자들이 클래스와 직관적으로 연계되어 활용되기 쉬울 때에만 사용하도록 주의합니다.

 


오버로딩의 규칙들

 

  1. 연산자 우선순위(Precedence)결합법칙(Associativity)는 변경될 수 없습니다.
  2. arity가 변경될 수 없습니다. (연산자의 인수, 또는 피연산자의 갯수가 변경될 수 없습니다)
  3. C++에서 기본적으로 사용하는 연산자들이 아닌 새로운 연산자를 만들어낼 수 없습니다.
  4. 원시 타입(Primitive Type) 에 대한 연산자는 오버로딩할 수 없습니다.
  5. [], (), ->, = 연산자는 무조건 멤버 함수로 선언되어야 합니다.
  6. 이외의 연산자는 멤버 메소드 또는 글로벌 함수로 선언될 수 있습니다.