연산자 오버로딩-기본적인 연산자

Challenge and Frustration·2021년 9월 29일
0

오버로딩(overloading)

오버로딩은 ad hoc polymorphism의 일종으로 기본적으로 함수 오버로딩과 연산자 오버로딩은 궤를 같이한다.

필요성

난 처음 이걸 보자마자 선형대수학에서 배운 벡터 공간이 생각이 났다. 어떤 벡터 공간에서 벡터 간의 연산은 정해진 것이 아니라 사람에 따라 다르게 정의할 수 있다.
연산자의 오버로딩도 마찬가지이다.

객체지향에서 데이터에 중심이 있는 객체 간에 연산이 안된다는 것은 좀 많이 아쉽다. 이게 가능하다면 벡터 연산, 행렬 등에서 요긴하게 쓰일텐데 말이다.

그리하여 연산자 오버로딩이 필요한 것이다.

오버로딩의 개념

'+' 이 연산자는 수학에서 아주 다양한 케이스에 사용된다.
즉, 인간은 저 기호를 아주 다양하게 쓰는데 헷갈리지도 않고 신통방통하게 잘 쓴다.
그 근거는 피연산자가 다르기 때문에 피연산자를 보고 아, 이렇게 해야겠구나하고 생각하는 것이다.
그것을 구현하는 방법이 바로 연산자 오버로딩이다.
피연산자를 달리하여 하나의 연산자에 다양한 의미를 부여하는 것이다.

그렇다면 어떤 방식으로 의미를 부여할까??
연산자에 기능을 불어넣는 것. 바로 함수를 통해서 이루어진다.


문법

이제 함수를 통해서 연산자의 polymorphsim을 구현한다는 것을 알겠다.
함수는 구현하기 나름이니 어떤 연산도 정의할 수 있을 것이다.
먼저 간단하게 생각해보면 전역함수를 고려해볼 수 있다.
어떤 종류의 인자든 넣어주고 결과를 얻어낼 수 있다.
하지만 C++은 객체지향 언어이다. 많은 경우 연산자를 정의하는 함수는 멤버함수로 많이 사용한다.

obj1 + obj2

위와 같은 식을 컴파일러가 만나면 피연산자를 보고 어떤 함수를 호출할지 결정한다. 즉, 연산자는 컴파일러에겐 함수로 보인다.
멤버함수로 오버로딩된 경우
obj1.operator+(obj2)와 같은 형태로 인식한다.
전역함수로 오버로딩된 경우
operator+(obj1, obj2)와 같은 형태로 인식한다.


그렇다면 ++num, num++ 같은 단항 연산자 같은 경우에는 어떤 문법으로 오버로딩할까??
위의 문법은 이항연산자를 의미하는 것 아닌가?
똑같다고 보면 된다.
++obj를 고려해보자.
만일 연산자 오버로딩이 멤버함수를 통해 정의되었다면 위의 연산식을 컴파일러는 obj.operator++()로 인식할 것이다.
만일 연산자 오버로딩이 전역함수를 통해 정의되었다면 위의 연산식을 컴파일러는 operator++(obj)로 인식할 것이다.

헌데 문제가 생겼다. 전위증감연산자나 후위증감연산자나 연산자의 형태가 ++,--인 것이다.
즉, 함수의 이름이 같아지는 문제가 생긴다.
함수의 이름은 같지만 두 식은 다른 함수를 호출해야한다.
여기서 두 가지 가능성이 떠오를 수 있다.
하나는 함수 오버로딩이고 다른 하나는 함수 오버라이딩이다.

둘 다 동일한 함수 이름을 통해 서로 다른 내용을 실행할 수 있다. 하지만 이 경우에는 상속과 아무 관계가 없고 고로 상속을 전제로 하는 함수 오버라이딩은 사용할 수 없다.
고로 함수 오버로딩을 이용해 문제를 해결한다.

전위 증감 연산자: obj.operator++(), operator++(OBJ obj)
후위 증감 연산자: obj.operator++(int), operator++(OBJ obj, int)

이렇게 정의한다. 근데 좀 이상하다. 뜬금없이 매개변수가 왜 등장하는가?

이는 함수 오버로딩을 의미하는 매개변수로 하나의 약속이자 형식일 뿐이다. 원래 함수 오버로딩은 주로 매개변수의 차이로 이루어지니까.

이런 식으로 연산자 오버로딩을 왜 쓰고 무엇이며 어떻게 하는지 알아봤다.

0개의 댓글

관련 채용 정보