programming/cpp

[C++] friend와 Operator Function

C++의 friend와 인간관계에서의 friend는 다르다.


강사님은 지금부터 나의 모든 것을 사용할 수 있다.


==> C++의 friend는 한쪽 방향(접근 제어자의 의미가 사라진다, 모두 public으로 인식)

friend는 일방적이다.



(노트필기할것)

friend 선언은 3개가 있다.


friend의 종류

1. friend class

2. friend method(특정 메소드에만 친구가 된다, 다른 메소드는 원래 의미 그대로) - 쓰는 걸 본 적이 없다

3. friend function(외부 함수를 말한다, 밖에 있는 함수를 친구로 지정)


3 -> 1-> 2순으로 많이 쓴다


friend는 많이 쓰면 좋을까?

friend는 객체지향의 특징인 캡슐화를 파괴한다


하지만 문법적으로는 캡슐화 파괴가 맞다

개념적으로는 코드의 확장이라는 의미가 생긴다

더 깊게 들어가면 쟤는 내 멤버여야 하는데 문법적으로 그럴 수 없는 구조일 때


그렇다면 friend는 어디서 많이 쓸까?

연산자 함수는 멤버함수로도 외부함수로도 만들 수 있다


ex. 3 + 객체

연산자 함수 : 체와 객체, 객체와 데이터를 산술 연산자로 계산이 되게 해주는 함수



friend라는 개념은 접근하겠다 느낌



연산자 함수

: 객체를 가지고 연산을 할 수 있게끔 도와주는 함수


(객체 + 숫자가 될 수도 있고 숫자 + 객체가 될 수도 있고, 객체 + 객체가 될 수도 있다)

개발자가 직접 제공해야 한다 그대신 불러준다면 언제든 연산을 하겠다


연산자 함수에서 제일 중요한게 뭘까?

1. 원래 의미를 바꾸지 말라!

2. 새로운 연산자의 정의를 하지 마라! (할 수 있지만 하지 말라!)

ex. new도 연산자다 new의 기능만 구현해야 한다


연산자 함수를 만드는 방법은 2가지

1. 멤버 함수

2. 외부 함수



객체가 먼저 오는 것들은 객체를 통해서 갈 수 있지만

4.a 는 될 수가 없다

이런 경우는 외부 함수로 만들 수 밖에 없고 이 경우에는 friend로 지정해서 멤버 함수와 같은 서비스로 제공하겠다가 취지

 

 

Overloading으로 재 정의할 수 없는 연산자 4가지

.

.*

::

? : (삼항 연산자)



연산자 오버로딩의 제약 사항

연산자 오버로딩은 다음과 같은 상황에서는 사용할 수 없다.

http://snowdeer.github.io/c++/2017/08/31/cpp11-operatior-overloading/ 님의 포스팅 참고하였습니다

  • 새로운 연산자 기호를 적용할 수 없음.
  • 오버로딩할 수 없는 연산자도 있음. 대표적으로 ::, sizeof, 삼항 연산자 ?: 등은 오버로딩 못함.
  • 연산자의 인자의 개수는 변경 불가능. 예를 들어 ++는 한 개의 인자를 갖고, +는 두 개의 인자를 가짐.
  • 연산자의 우선 순위와 결합 규칙은 변경 안됨.
  • 내장 타입(기존에 이미 정의되어 있는 데이터 타입들. 예를 들어 int 등)에 대한 연산자 재정의 불가능.

 


멤버 함수와 전역 함수


클래스 멤버 함수로 연산자를 구현하면 연산자의 좌항이 반드시 해당 클래스 객체여야 한다. 전역 함수로 구현하면 좌항에 다른 타입이 와도 상관없다.


ex. cout << aa;    →    cout.operator<<(aa);    →   cout의 클래스 내부에 operator<< 함수가 구현되어야 하는데 ostream은 이미 만들어진 표준 헤더파일이기 때문에 만들 수 없음!


오버로딩해서는 안되는 연산자

 예를 들어 주소 연산자 operator&를 오버로딩해버리면 C++ 언어의 가장 기초적인 기능인 변수의 주소값 얻기를 바꿔 버리기 때문에 굉장히 혼란스러워지고 어떤 결과를 초래할 지 알기 어렵게 된다.


 주소 연산자와 더불어 논리 연산자 operator&&operator||도 오버로딩해서는 안된다. 이 연산자들을 오버로딩하면 C++의 논리 계산 생략 원칙이 동작하지 않게 된다.


 마지막으로 콤마 연산자 operator,도 오버로딩해서는 안된다. 여기서 ,는 오타가 아니다. C++에서는 콤마도 연산자다. 순차 연산자라고 불리며 분리된 두 표현식을 하나의 구문으로 만들어 왼쪽에서 오른쪽으로 실행되도록 그 순서를 보증한다. 이 연산자를 오버로딩해야 할 상황은 상식적으로 생각하기 어렵다.