기존의 제공하고 있는 연산자를 재정의하여 사용자 정의 클래스로 사용하는 것을 말한다.
첫번째 자료의 연산자들은 오버로딩이 가능하다. 하지만 두번째 자료처럼 불가능한 연산자들도 존재한다. 하지만 대부분은 가능하다.
Point &operator+(Point &a)
{
num = num + a.num;
return *this;
}
위 코드가 대표적인 예시이다. 오버로딩하고 싶은 클래스에 operator를 활용하여 원하는 연산자를 쓴다. 그 이후에 정의를 해주는 방식이다.
++연산자 같은 경우, ++를 앞에 둘지, 뒤에 둘지에 따라 계산과정이 달라진다. 이를 고려해주는 연산자 오버로딩이 필요하다.
prefix
이는 연산자를 앞에 두는 방식이다. (ex. ++a)
이때는 값을 계산하고 이를 return 하면 된다.
postfix
이는 연산자를 뒤에 두는 방식이다. (ex. a++)
이 부분이 고려할 부분이 많다. 이는 출력을 하고 이후에 계산을 해야된다.
따라서 ++를 해주기 전에 값을 저장해놓고 있다가, return은 저장한 값을 주어야 한다.
하나 주의해야 될 점은 postfix 같은 경우, 매개변수로 int형을 하나 준다. 이것이 쓰이지는 않지만 postfix 연산이라는 것을 알려주는 암묵적 표현이다.
아래 코드가 이에 대한 예시이다.
//1. prefix
cal &operator++() {
num++;
return *this;
}
//2. postfix
cal operator++(int) {
//값 저장
cal charge = *this;
//더하기는 해주고,
num++;
// return은 저장해준 값으로....
return charge;
}
==는 두 값이 맞는지 비교해주는 연산자로 선언해줄때 자료형이 bool
형태이이어 한다. 맞다면 true를 틀리다면 false를 해주면 된다. 맞다는 기준은 본인이 함수 안에 정의하면 된다.
bool operator==(cal& a) {
if (num == a.num) {
return true;
}
else {
return false;
}
}
이 부분이 연산자 오버로딩 중에서 제일 복잡하다고 할 수 있다.
우선, 코드를 먼저 확인해보자
class cal {
private:
int num;
public:
cal();
cal(int a);
friend ostream& operator<<(ostream& output, const cal& a);
friend istream& operator>>(istream& input, cal& a);
};
ostream& operator<<(ostream& output, const cal& a)
{
output << a.num;
return output;
}
istream& operator>>(istream& input, cal& a) {
input >> a.num;
return input;
}
여기서 중요하게 봐야할 점은 friend
와 ostream& ouput
을 다시 리턴해준다는 점이다.
cout<< 같은 경우는 otream 이라는 클래스에 있는 것이기 때문에 기존 클래스 안에 정의해주는 것이 아니라 밖에 정의를 해야된다.
밖에 정의했기 때문에 cal& a라는 곳에 멤버변수(private)에 접근할 수 없다. 따라서 friend를 클래스 안에 선언해줌으로써 이를 가능하게 한다.
otstream에 output이라는 변수를 선언해주고 이를 통해 받고 싶은 값을 받아 할당한다. 그리고 cout 과정이 끝났다면 output을 다시 리턴해준다.
이 이유는 cout<<a<<b<<c;
라는 코드가 있을때 cout<<b<<c;
이런식으로 진행하기 위함이다.
cin>> 도 마찬가지이며, 여기서 하나 다른점은 cout<<같은 경우, 넣는 클래스 변수에 const가 붙는다는 점이다. 이 이유는 중요한 건 아니지만 출력하는 역할이기 때문에 변수를 굳이 바꾸지 말라는 제약을 둔 것이다.