연산자 오버로딩
- 함수를 오버로딩 하는 것 처럼 연산자도 오버로딩할 수 있다.
- 즉 연산자의 기본 기능 이외 다른 기능을 매개변수에 따라 추가할 수 있다.
#include <iostream>
using namespace std;
class Point
{
private:
int xpos, ypos;
public:
Point(int x=0, int y=0) : xpos(x), ypos(y)
{ }
void ShowPosition() const
{
cout << "xpos: " << xpos << " ypos: " << ypos << endl;
}
Point operator+(const Point &pos)
{
Point point(xpos+pos.xpos, ypos+pos.ypos);
return point;
}
};
int main()
{
Point pos1(10, 20);
Point pos2(3, 4);
Point pos3;
pos3 = pos1 + pos2;
pos3.ShowPosition();
}
xpos: 13 ypos: 24
Process returned 0 (0x0) execution time : 0.013 s
Press any key to continue.
pos1 + pos2는 pos1.operator+(pos2)로 해석되어서 컴파일된다.
이는 operator 키워드를 통한 일종의 약속이다.
연산자 오버로딩 방법
- 멤버함수에 의한 연산자 오버로딩
- 전역함수에 의한 연산자 오버로딩
1의 방법은 위에서 보였다시피 pos1의 멤버함수에 operator+(Point pos)를 선언함으로써 가능하다
2의 방법은
#include <iostream>
using namespace std;
class Point
{
private:
int xpos, ypos;
public:
Point(int x=0, int y=0) : xpos(x), ypos(y)
{ }
void ShowPosition() const
{
cout << "xpos: " << xpos << " ypos: " << ypos << endl;
}
friend Point operator+(const Point &pos1, const Point &pos2);
};
Point operator+(const Point &pos1, const Point &pos2)
{
Point pos(pos1.xpos+pos2.xpos, pos1.ypos+pos2.ypos);
return pos;
}
int main()
{
Point pos1(10, 20);
Point pos2(3, 4);
Point pos3;
pos3 = pos1 + pos2;
pos3.ShowPosition();
}
friend(함수내에서 클래스의 private 영역에 접근가능) 선언을 통해서 +연산자에 오버로딩이 되어있다.
+= 연산자 오버로딩
Point& operator+=(const Point &pos)
{
xpos = xpos+pos.xpos;
ypos = ypos+pos.ypos;
return *this;
}
연산자 오버로딩 주의사항
1. 본래의 의도를 벗어난 형태의 연산자 오버로딩은 좋지 않다.
pos1 + pos2를 했는데 곱한 결과가 나온다면 당황스러울 것이다.
2. 연산자의 우선순위와 결합성은 바뀌지 않는다.
덧셈과 곱셈이 있다면 곱셈 연산이 먼저 시행된다.
3. 매개변수의 디폴트 값 설정이 불가능하다.
자료형에 따라 연산자를 오버로딩 한 함수의 호출이 결정되기에 디폴트 값이 정해질 수 없다.
4. 연산자의 순수 기능까지 뺏을 수 없다.
int operator+(const int num1, const int num2)등은 정의할 수 없다.
단항 연산자의 오버로딩
Point& operator++()
{
xpos++;
ypos++;
return *this;
}
Point operator-()
{
Point pos(xpos*(-1), ypos*(-1));
return pos;
}
전위증가와 후위증가
++pos => pos.operator()
pos++ => pos.operator++(int)
여기서 int는 후위연산을 구분하기 위해 붙이는 것이상의 의미는 없다.
const Point operator++(int)
{
const Point retobj(xpos, ypos);
xpos += 1;
ypos += 1;
return retobj;
}
const Point operator--(Point &ref, int)
{
const Point retobj(ref);
ref.xpos-=1;
ref.ypos-=1;
return retobj;
}
반환형에 const 선언
=operator++함수의 반환으로 인해서 생성되는 임시객체를 const로 생성하겠다.
=/= retobj가 const로 선언되어서 ( 반환의 과정에서 새로운 객체가 생성되기때문에 영향을 안준다 -복사생성자 )
반환형에 const 선언을 하는 이유는 다음을 막기 위해서이다.
(pos++)++; // 컴파일 에러
(pos--)--; // 컴파일 에러
(Point형 const 임시객체)++;
(Point형 const 임시객체).operator++();
operator++가 const 함수가 아니기때문에 컴파일 에러가 발생한다.
이는 다음을 허용하지 않는 C++의 연산특성을 반영한 결과이다.
int main()
{
int num = 1;
(num++)++; // 컴파일 에러
(num--)--; // 컴파일 에러
return 0;
}
'프로그래밍 언어 > 열혈 C++' 카테고리의 다른 글
11-1 연산자 오버로딩2 (0) | 2022.03.17 |
---|---|
10-1. 연산자 오버로딩 1 (0) | 2022.03.14 |
08 상속과 다형성 by 윤성우의 열혈 C++ (0) | 2022.03.08 |
07 상속의 이해 by 윤성우의 열혈 C++ (0) | 2022.03.08 |
06 const, friend, static, mutable by 윤성우의 열혈 C++ (0) | 2022.03.07 |