C++ 연산자 오버로딩(operator overloading)

프로그래밍/C++ 2019.10.15 댓글 Plorence

연산자 오버 로딩은 C++가 가진 다형 특성의 한 예입니다.

C++에서는 *연산자로 예시를 들면 주소가 적용되면 해당 주소에 접근하고, 피연산자 2개 사이에 *연산자를 쓴다면 수행하는 것은 곱셈을 연산합니다.

이렇게 C++는 피연산자의 개수데이터형을 판단하여 어떤 연산을 수행할지 결정할 수 있습니다.

operatorOp(argument)

Op에는 연산자가 들어가고 그 앞 'operator'는 키워드입니다.

연산자 오버로딩은 멤버 함수가 아닌 함수에서도 가능합니다.

 

예시 - 멤버 함수

클래스의 데이터 은닉을 통하여 데이터 멤버에 접근하는 멤버 함수를 정의하지 않고, 연산자 오버 로딩을 통하여 오버 로딩된 연산자를 가지고 해당 데이터 멤버에 값을 더하는 클래스를 정의해봅시다.

이때 왼쪽 피연산자 객체의 멤버에 더하는게 아니고 새로운 객체를 만들어 이 객체에 더하고, 리턴할 겁니다.

#include <iostream>
class Person {
public:
       int age;
       Person(int p_age) {
              age = p_age;
       }
       Person operator+(int a) { //+연산자 오버로딩!
              Person temp(age+a);
              return temp;
       }
       void Show() const {
              std::cout << age << "\n";
       }
};
int main(void) {
       Person per = Person(11);
       per.Show();
       per = per + 1; //age에 1을 더한다
       per.Show();
       per = per.operator+(1); //age에 1을 더한다.
       per.Show();
       return 0;
}

여기서의 핵심은 객체를 생성한 이후부터입니다.

per + 1; //age에 1을 더한다
per.operator+(1); //age에 1을 더한다.

이 둘의 결과(역할)는 동일하지만 차이점은 1번째 줄은 연산자 표기를 사용하였고 2번째 줄은 멤버 함수 표기를 사용하였습니다.

 

예시 2 - 멤버 함수가 아닌 함수

함수에서도 연산자 오버 로딩이 가능한데, 이 경우에는 해당 멤버에 접근이 가능해야 합니다.(관련된 friend는 추후 설명)

#include <iostream>
class Person {
public:
       int age;
       Person(int p_age) {
              age = p_age;
       }
       void Show() const {
              std::cout << age << "\n";
       }
};
Person operator+(Person a,int b) { //+연산자 오버로딩!
       Person temp(a.age + b);
       return temp;
}
int main(void) {
       Person per = Person(11);
       per.Show();
       per = per + 1; //age에 1을 더한다
       per.Show();
       return 0;
}

멤버 변수 a는 public이므로 에러가 발생하지 않습니다.

 

연산자 오버 로딩의 제약

  • 오버 로딩된 연산자는 적어도 하나의 피연산자가 사용자 정의 데이터형이어야 합니다. 1.1 - 1.1 = 0.0 이 아닌 1.1-1.1=2.2(합)이 되도록 재정의를 할 수 없습니다.

  • 오버로딩된 연산자를 원래의 연산자에 적용되는 문법 규칙을 위반하는 형식은 사용하면 안 됩니다.

  • 연산자의 우선순위도 변경할 수 없습니다.

  • 연산자 기호를 새로 만들 수 없습니다.

  • 아래의 표에 해당하는 연산자들은 오버 로딩이 불가능합니다.

  • 왼쪽의 피연산자는 반드시 사용자 정의 데이터형이어야 합니다.(멤버 함수일 때)

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

연산자

설명

sizeof

sizeof 연산자

,

멤버 연산자

.*

멤버 지시 포인터 연산자

::

사용 범위 결정 연산자

?:

조건 연산자

typeid

RTTI 연산자

const_cast

데이터형 변환 연산자

dynamic_cast

데이터형 변환 연산자

reinterpret_cast

데이터형 변환 연산자

static_cast

데이터형 변환 연산자

 

멤버 함수에서만 오버로딩이 가능한 연산자

연산자

설명

=

대입 연산자

()

함수 호출 연산자

[]

배열 인덱스 연산자

->

클래스 멤버 접근 포인터 연산자

연산자 오버 로딩을 할 때 주의해야 할 점

연산자를 오버 로딩할 때 행동에 맞는 연산자의 의미를 써야 합니다(내부 연산은 덧셈인데 *연산자를 오버 로딩하는 경우)

 

댓글