문과 코린이의, [C. C++] 기록/C++ 이론

[문과 코린이의 IT 기록장] C,C++ - 연산자 오버로딩 2 : 단항 연산자 오버로딩(증감 연산자 오버로딩, 전위증가 및 후위증가의 구분)

벼리네 2021. 2. 21. 17:45
반응형

[문과 코린이의 IT 기록장] C,C++ - 연산자 오버로딩 2 : 단항 연산자 오버로딩

(증감 연산자 오버로딩, 전위증가 및 후위증가의 구분)


 1. 증감 연산자 오버로딩

++ pos; // pos는 객체
a. 맴버함수로 오버로딩하는 경우 : pos.operator++();
b. 전역함수로 오버로딩하는 경우 : operator++.(pos);

 

 

 

#include <iostream>

using namespace std;

 

class Point { // point 클래스

private:

  int xpos, ypos;

public:

  Point(int x = 0, int y = 0) : xpos(x), ypos(y){ } // 생성자 (x=0, y=0으로 초기화)

  void ShowPosition() const { // [xpos, ypos] 출력 함수

    cout << '[' << xpos << ", " << ypos << ']' << endl;

   }

Point& operator++() {
// 반환형이 참조형(point&)인, operator++함수
// ++연산자가 맴버함수의 형태로 오버로딩

  xpos += 1;

  ypos += 1;

  return *this // 함수 체이닝 기법을 사용하기 위해 작성. 연산된 참조값(객체 그 자체의 값) 전달.

ex ) Point & ref = ++pos = pos.operator++()이다. 반환된 *this, 즉 객체 자신에 대한 정보(참조값)이 존재하고, 그 값을 반환한다(반환형이 참조형이기 때문). 이와 같이 객체의 참조값을 반환하는 함수의 형태가 존재해야, 체이닝기법이 가능하다.

This 포인터 참고사항

 

}

friend Point& operator--(Point& ref); // Point & operator--함수는, Point 클래스의 맴버에 접근 가능하다.

};

 

Point& operator--(Point& ref) { // 인자로 전달된 pos객체를, 참조자 ref로 받는다.

  ref.xpos -= 1;

  ref.ypos -= 1;

  return ref // 참조형(Point&이기 때문에)으로 반환한다.(복사본 x) (this포인터 사용은 맴버함수에서 사용)

}

 

int main() {

Point pos(1, 2);

++pos; // pos.operator++();

pos.ShowPosition();

--pos; // operator--.(pos)

pos.ShowPosition();

 

++(++pos); // ++(pos.operator++()) = ++(pos의 참조값) = (pos의 참조값).operator++();

pos.ShowPosition();

--(--pos); // --(operator--.(pos)) = --(pos의 참조값) = operator--.(pos의 참조값);

pos.ShowPosition();

return 0;

}

 




 2. 전위증가 및 후위증가의 구분

[ C++에서의 전위연산 vs 후위연산 해석규칙 ]

(1) ++

 a. ++pos : pos.operator( );
 b. pos++ : pos.operator++(int); 

(2) --

 a. --pos : pos.operator--( );
 b. pos-- : pos.operator--(int);

cf ) int는 구분목적이지, 의미를 지니지는 않는다.


ex )

 

#include <iostream>

using namespace std;

 

class Point { // Point 클래스

private:

  int xpos, ypos;

public:

Point(int x=0, int y=0): xpos(x), ypos(y){ } // 생성자

void ShowPosition() const { // xpos, ypos 출력 (const 맴버함수 : 호출한 객체의 맴버변수를 변경하지 못하는 함수)

   cout << '[' << xpos << ", " << ypos << ']' << endl;

}

Point& operator++() { // 전위증가, 반환형은 참조형.

  xpos += 1;

  ypos += 1;

  return *this // 참조값(객체) 그 자체를 반환

}

const Point operator++(int) { // 후위증가

  const Point retobj(xpos, ypos); // const Point retobj(*this); (복사생성자 구문과 같다) / 먼저 기존값을 복사해놓고, +1계산.

  xpos += 1;

  ypos += 1;

  return retobj; // 기존값(참조값 = 객체 그 자체)을 반환함으로서, 후위증가 가능

}

friend Point& operator--(Point& ref);

friend const Point operator--(Point& ref, int);

};

 

Point& operator--(Point& ref) { // 전위감소

  ref.xpos -= 1;

  ref.ypos -= 1;

  return ref;

}

 

const Point operator--(Point& ref, int) { // 후위감소

  const Point retobj(ref); // const 객체라한다

  ref.xpos -= 1;

  ref.ypos -= 1;

  return retobj;

}

 

 

int main() {

Point pos(3, 5);

Point cpy;

 

cpy = pos-- // pos.operator--(int);

cpy.ShowPosition(); // 후위증가는 ;를 만난 이후에 연산이 진행된다. 따라서 cpy는 연산이 진행되기 전의 값을 지닌다.

pos.ShowPosition(); // 위와 같은 원리로, pos는 연산 후의 값을 지니게 된다.

 

cpy = pos++; // pos.operator++(int);

cpy.ShowPosition();

pos.ShowPosition();

return 0;

}

 


* 유의사항
- 아직 공부하고 있는 문과생 코린이가, 정리해서 남겨놓은 정리 및 필기노트입니다.
- 정확하지 않거나, 틀린 점이 있을 수 있으니, 유의해서 봐주시면 감사하겠습니다.
- 혹시 잘못된 점을 발견하셨다면, 댓글로 친절하게 남겨주시면 감사하겠습니다 :)
반응형