도순씨의 코딩일지

C++ :: 연산자 오버라이딩, 단항 연산자의 오버로딩, 전위증가와 후위증가 오버로딩 본문

𝐏𝐑𝐎𝐆𝐑𝐀𝐌𝐌𝐈𝐍𝐆/𝐂++

C++ :: 연산자 오버라이딩, 단항 연산자의 오버로딩, 전위증가와 후위증가 오버로딩

도순씨 2020. 8. 29. 00:00

🌼 operator+ ❓

⭐️FirstOperationOverloading.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#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 << ", " << ypos << ']' << endl;
    }
    Point operator+(const Point &ref){
        Point pos(xpos + ref.xpos, ypos + ref.ypos);
        return pos;
    }
};
 
int main(void){
    Point pos1(34);
    Point pos2(1020);
    Point pos3 = pos1.operator+(pos2);
 
    pos1.ShowPosition();
    pos2.ShowPosition();
    pos3.ShowPosition();
    return 0;
}
cs

 

⭐️FirstOperationOverloading.cpp 실행 결과

1
2
3
[3, 4]
[10, 20]
[13, 24]
cs

 

21행을 조금 유의깊게 살펴봅시다. 위에서 Point operation+ 라는 이름의 신기한 형태의 함수가 선언되었습니다. 21번째 라인에서 po1 객체의 멤버함수 operator+를 선언하여 인자로 pos2를 전달하고 있습니다. 이 결과로 새로운 Point 객체 pos3를 초기화하게 됩니다. 

 

조금만 변형해서 살펴보도록 합시다.

 

⭐️ OverloadingOperation.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#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 << ", " << ypos << ']' << endl;
    }
    Point operator+(const Point &ref){
        Point pos(xpos + ref.xpos, ypos + ref.ypos);
        return pos;
    }
};
 
int main(void){
    Point pos1(34);
    Point pos2(1020);
    Point pos3 = pos1 + pos2;
 
    pos1.ShowPosition();
    pos2.ShowPosition();
    pos3.ShowPosition();
    return 0;
}
cs

 

⭐️ OverloadingOperation.cpp 실행결과

1
2
3
[3, 4]
[10, 20]
[13, 24]
cs

 

21번째 라인의 내용이 바뀌었습니다. pos1과 pos2를 더하여 pos3에 저장하라는 의미로 해석할 수 있습니다. 하지만 결과는 동일합니다. pos1+pos2가 pos1.operator+(pos2)와 같은 표현임을 알 수 있습니다.

 

그렇다면 pos1.operator+(pos2)가 pos1 + pos2로 해석된다면 pos1.operator-(poe2)도 존재하겠죠?

 

🌼 연산자를 오버로딩하는 두 가지 방법

연산자를 오버로딩하는 방법은 크게 두 가지로 나눌 수 있습니다.

💡 멤버함수에 의한 연산자 오버로딩

💡 전역함수에 의한 연산자 오버로딩

 

예시를 들어보자면 연산자를 '어떻게' 오버로딩 했느냐에 따라서 두 가지로 나뉘게 됩니다.

ex ) pos1 + pos2

 

💡 멤버함수에 의한 연산자 오버로딩

1
pos1.operator+(ops2);
cs

💡 전역함수에 의한 연산자 오버로딩

1
operator+(pos1, pos2)
cs

 

예제를 통해서 전역함수 기반으로 오버로딩을 해 봅시다.

 

⭐️ GFunctionOverloading.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#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 << ", " << 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(void){
    Point pos1(34);
    Point pos2(1020);
    Point pos3 = pos1+pos2;
 
    pos1.ShowPosition();
    pos2.ShowPosition();
    pos3.ShowPosition();
    return 0;
}
cs

 

⭐️ GFunctionOverloading.cpp 실행 결과

1
2
3
[3, 4]
[10, 20]
[13, 24]
cs

 

🌼 멤버 함수 기반으로만 오버로딩이 가능한 연산자

= 대입 연산자
() 함수 호출 연산자
[] 배열 접근 연산자(인덱스 연산자)
-> 멤버 접근을 위한 포인터 연산자

 

🌼 연산자 오버로딩 주의사항

💡 본래의 의도를 벗어난 형태의 연산자 오버로딩을 지양하자.

연산자 오버로딩은 잘못 사용하면 프로그램이 복잡해진다. 따라서 연산자의 본래 의도를 충실하게 반영하여 혼란스러운 부분을 최소화해야 한다.

 

💡 연산자의 우선순위와 결합성은 바뀌지 않는다.

💡 매개변수의 디폴트 값 설정이 불가능하다

💡 연산자의 순수 기능까지 빼앗을 수는 없다 .

 

🌼 단항 연산자의 오버로딩

증가, 감소 연산자는 ++와 --가 있습니다. 단항 연산자를 오버로딩하면 다음과 같은 형태로 오버로딩됩니다.

 

 🌼 전위 증가와 후위 증가의 구분

++연산자와 --연산자는 위치에 따라서 연산 결과가 달라지는 경우가 많습니다. 혼란을 막기 위해서 C++에서는 전위 및 후위 연산에 대해 규칙을 정해놓고 있습니다.

 

 

 

📜 출처

윤성우(2010). 윤성우 열혈 C++ 프로그래밍. 오렌지미디어.

Comments