Back-end/C++

22. 04. 04 - 연산자 오버 로딩 : 더하기, 전치형-후치형, 일반 함수, 배열 첨자, 대입

giggs 2022. 4. 12. 09:58

 

 

연산자 오버 로딩

 

  • java에서는 없다.
  • 연산기호를 사용하게 해 놓으면 직관적인 면에서 유용하다
  • 연산자 오버 로딩으로 ' + ' 를 해놓고 기능은 뺄셈 기능으로 해놓을 수도 있긴 하지만
  • 연산기호에 맞는 기능 구현해놓는 것이 기본이다.
  • 우리가 쓰던 cout << endl;에서  ((( << ))) 도 연산자 오버 로딩이었다!

 

 

 


 

 

 

 

연산자 오버 로딩 : operator +

 

 

 

복소수

  • a, b가 실수이고 a + bi 꼴의 수
  • 10과 10 i 출력

 

내가 만든 클래스에 = 내가 만든 데이터 타입

연산 기호를 사용할 수 있나요?

 

 

No!

 

 

객체 + 객체 : 가능? No!

 

 

 

But!

C++에서 제공하는 ' 연산자 오버 로딩 ' 기능으로 가능하다!

 

 

 


 

 

operator + ( )

 

연산자 오버로딩 - operator + ( ) 부분 Check !

 

 

 

오버로딩한 연산자 ' + ' 사용 해보기

 

 

 

 

  • 91번 하고 92번 하고 똑같은 것이다.
  • 우리가 만든 Complex 객체 a로 Complex 객체 b 더하기 가능 
  • a클래스에서 함수 호출하는 것이랑 똑같은 것

 

 

 


 

 

 

 

연산자 오버 로딩 : operator ++ ( 전치형 / 후치형 )

 

 

 

후치형

일단 값을 대입해준 다음에- 값 증가

순서 1. 일단 이전의 값을 temp에 기록해준다.

순서 2. 값을 증가시킨다.

순서 3. 원래의 값 temp를 대입해준다.

 

 

 

 

전치형

값 증가한 다음에 대입

순서 1. 값을 증가시킨다.

순서 2. 대입시킨다.

 

 

 

 

후치형 전치형 내용 Check

 

 

 

 

몰라도 코드 작성하는 것은 지장 X.

다른 사람이 사용한 거 이해하는데 좋음

물론 내가 사용할 수도 있고

 

 

 

 


 

 

 

 

연산자 오버 로딩 - 일반 함수

 

 

보통 멤버 함수로 만들지만 일반 함수로 만들어야 하는 경우가 있다.

바로 - (((  연산 기호의 왼쪽에 위치해야 하는 경우  )))

 

 


 

 

연산 기호의 왼쪽에 위치해야 하는 경우란?

 

 

연산자 오버 로딩(일반 함수로 버전)  - 기본 세팅

 

 

Complex complex = 10;

cout << complex << endl;

 

 

cout << complex 

  • 이게 되려면 cout은 Complex객체를 받는 연산자 함수 --- << ---필요하다 .
  • complex는 내가 만든 Complex 데이터 타입으로 만들어진 객체로 컴파일러는 미리 알 수 없다
  • 연산자가 만들어져 있을 리가 없다. 

 

 

 

complex . cout ( )operator<<

  • 그리고 cout을 Complex 클래스 안에 만들면 ( 멤버 함수로 만들면 )
  • cout이 연산자 왼쪽에 올 수 없다.
  • complex << --- 식으로 사용해야 된다. - 객체로  멤버 함수 호출하는 식
  • << Complex ---- 식으로 사용할 수 없다. - 함수로 객체를 호출하는 식

 

 

 

이처럼 멤버 함수로 구현할 수 없을 때 - 연산자의 왼쪽에 와야 하는 경우

일반 함수로 연산자 오버 로딩 

 

 

 

 

## Check Point 

  • 클래스 외부의 일반 함수로 클래스 내부의 멤버 함수를 호출하려면
  • Set( ) / Get ( ) 함수를 호출해서 접근해야 한다.
  • 이번에는 friend 키워드를 추가해서 - 친구 함수를 만들어주고
  • 이를 이용하여 접근하고, 연산자 오버 로딩 실습

 

 

 

 

일반 함수니까 set / get 함수를 호출해서 접근했었다. - ref . Real( ) 과 ref . Imaginary( )

 

 

Set( ) / Get( ) 함수로 멤버 변수 접근

 

 

 

함수에 friend 키워드 추가해주면 친구 함수가 되고 - 친구의 private영역 접근 가능하다..

 

friend 클래스에도, 함수에도 사용 가능!

 

 

friend 함수로 해주고 멤버 변수를 직접 호출

 

 

이처럼 일반 함수 ostream으로  연산자 << 재정의

왼쪽 연산자 << ---- 오른쪽에 - Complex 객체를 받을 수 있게 재정의한 것이다.

 

 

이제 cout << complex ; 사용 가능

 

 

 

자바에는 연산자 오버 로딩 없다.

 

 

 


 

 

 

연산자 오버 로딩 : [  ] 배열 첨자

 

 

 

 

기본 세팅 

  • 배열에 값 초기화 / 출력하는 부분

 

 

 

SetIndex와 GetIndex로 사용하니까 직관적이지 않다.

 

 

이럴 경우 연산자 오버 로딩을 이용하여 배열 첨자 (((    [  ]    ))) 연산자 오버 로딩을 통해 직관적으로 바꿔보자.

 

 

 

 

 

 

 

 

22번 line에 - int& operator에서 & 주소 값으로 안 해주면 오류 난다. 이유는?

  • index로 2가 들어왔다고 가정
  • 참조 타입이 아닌 값으로 해주면
  • int ~~~ _arr [2]되어서 2칸 떨어진 곳의 값을 리턴하게 되는 것이다.
  • 공간이 아닌 값을 리턴 - 함수는 무엇을 리턴해줘야 하는지 항상 잘 생각해야 한다.
  • [ ] 연산자는 - 공간을 리턴해줘서 - 나중에 이 공간에 값을 대입하게 해 줄 것이다.

 

 

 

 

 

 

 

 

47번 풀어보면 아래와 같은 것

array[i] = i;
array . operator[ ] ( i ) = i;

 

 

 

함수가 리턴한 값( LeftValue )

i( Right Value )을  대입한 것이다.

함수가 리턴함 값이 참조 공간!!

함수가 리턴한 값이 참조 값이 아니라 값이었으면

오른쪽 value 대입 불가능

 

 

 

 

 


 

 

 

 

연산자 오버 로딩 : = 대입 연산자

 

 

  • 좌측과 우측의 데이터 타입이 동일하면 대입을 해준다.
  • 주소 값을 가진 경우 문제 발생
  • 오버로딩 필요

 

 

 

## 대입 연산자를 연산자 오버 로딩해서 사용할 경우 주의 사항

  • 좌측과 우측의 데이터 타입이 동일하면 대입을 해준다.
  • 주소 값을 가진 객체를 대입하는 상황 대비
  • 대입이 여러 번 일어나는 경우 대비

 

 

 


 

 

 

1. 주소 값을 가진 배열 대입 대비

 

array = array2; 상황 - ( array2 -> array로 대입 상황 )

좌측 우측 데이터 타입이 동일하므로 실행된다.

언젠가는 문제 발생.

 

 

 

 

array에 --- 10 / 2000번지가 저장

array2 -- 20 / 3000번지가 저장되어있었는데

 

 

array2에 저장되어있는 ---- 20 / 3000번지 그대로

array에게 대입되어서 array가 가지고 있던 원래의 데이터 미아됨 - 어디 있는지 모름

 

 

대입이 끝난 후

이제 array와 array2가 같은 주소를 사용하고 있기 때문에

복사 생성자 경우와 똑같이 에러 난다 -

이를 방지하기 위해

복사 생성자 경우와 같은 형식으로 재정의가 필요하다.

 

 

 

수행 로직은 복사 생성자와 동일

  • array의 size 가져오고
  • size만큼 공간 새로 만들어주고 ,
  • 새로운 공간에 array의 값 대입

 

 

 

22번 Line - 위에서 했던 - 배열 첨자 [ ] 연산자 오버 로딩과

30번 Line - 지금 하는 - 대입 = 연산자 오버 로딩의

 

 

return 데이터 타입과 return 값 다른 것 check !

 

 

 


 

 

 

다른 이유 :

대입 연산자를 이어서 사용할 경우를 대비

참조 값으로 리턴을 받고 그 값으로 /  다음 대입 연산을 실행하기 위해서

 

 

 

 

 

2. 대입 연산자를 이어서 사용할 경우를 대비해서

 

 

67번 풀어보면 69번이다 - 연산 끝난 후 그 데이터타입으로 다시 연산을 들어가야함으로 리턴 값과 데이터 타입 체크

 

 

 

 

return 데이터 타입 DynamicArray& 로 해주고

return 값 *this 로 해주어야 한다..

 

 

 

 

 

 

 

 


 

 

 

 


review


operator

연산자 오버 로딩이라는 새로운 기능을 배웠다.
내가 사용하고자 하는 연산 기호에
내가 원하는 기능으로 오버 로딩을 통하여
사용할 수 있게 해 줬다.

연산기호를 사용하지 않았을 경우보다
가독성도 좋아졌고, 직관적으로 보여서
코드를 이해하는 데에도 더 효율적이었다.

다만 대입 연산자처럼
연산자 오버 로딩의 하는 경우
주의할 점 체크해서 사용해야 할 것 같다.

연산자 + 와 ++ 실습할 때는
왜 굳이 이렇게 해야 되나 생각하다가
>> 기호를 사용할 때
왜 사용하는지 깨달음을.ㅎㅎ
연산자 오버 로딩 - 잘 사용하면 코드 길이도 줄고
코드도 깔끔해져서 가독성도 upup 될 것 같다.


##check point 
연산자 오버 로딩 - 일반 함수로 사용해야 하는 경우
friend 함수 / 대입 연산자 오버 로딩 부분