-
윤성우 열혈 C++ 프로그래밍 10장) 연산자 오버로딩 1(operator+, operator++, operator-, operator--, operator<<)PROGRAMMING/C++ 2024. 1. 7. 22:16
다음주 안에 끝내버린다는 마음으로! C++에서 중요한 연산자 오버로딩을 정리해보고자 한다.
(혹시 저작권에 문제가 있다면 수정하겠습니다!! 개인적인 공부용으로 정리함을 알려드립니당)
https://product.kyobobook.co.kr/detail/S000001589147
연산자 오버로딩
- 멤버함수에 의한 방법 👈🏻추천하는 방법
- 전역함수에 의한 방법(friend 사용)
만약 멤버함수와 전역함수에 의한 방법, 두 가지 방법으로 오버로딩한 경우, 멤버함수에 의한 오버로딩이 우선되어 호출된다. 하지만 가끔 오래된 컴파일러가 이 상황에서 컴파일 에러를 발생시키므로 이러한 상황은 가급적 만들지 말도록 하자!
pos1 + pos2 == pos1.operator+(pos2) // 멤버함수에 의한 오버로딩 pos1 + pos2 == operator+(pos1, pos2) // 전역함수에 의한 오버로딩
⭐연산자를 오버로딩한 함수도 const로 선언이 가능하다.(이 방법 추천@!)
// 전역함수로 오버로딩 예시 Point operator(const Point &pos1, const Point &pos2){ Point pos(pos1.xpos + pos2.xpos, pos1.ypos + pos2.ypos); return pos; }
멤버함수 기반으로만 오버로딩이 가능한 연산
: 객체를 대상으로 진행해야 의미 있으므로 전역함수가 아닌 멤버함수를 기반으로 한다!
= 대입 연산자 () 함수 호출 연산자 [] 배열 접근 연산자(인덱스 연산자) -> 멤버 접근을 위한 포인터 연산자 연산자 오버로딩시 주의사항
▪️ 본래의 의도를 벗어난 형태의 연산자 오버로딩 X
▪️ 연산자의 우선순위와 결합성은 바뀌지 않는다
▪️ 매개변수의 디폴트 값 설정이 불가능하다.
▪️ 기본 자료형의 연산 기능을 빼앗을 수 없다!
단항연산자 ++,--
// 전위연산자 ++pos == pos.operator++(); // 멤버함수로 오버로딩된 경우 ++pos == operator++(pos); // 전역함수로 오버로딩된 경우 // 후위연산자 pos++ == pos.operator++(int); // 멤버함수로 오버로딩된 경우 pos++ == operator++(pos, int); // 전역함수로 오버로딩된 경우 //키워드 int를 이용해 후위연산을 나타내고 있으며, int가 인자를 나타내는건 절대 아니다!
- 전위 증가/감소 연산자의 경우 참조자를 반환하기 때문에 ++(++num), --(--num)이 가능하다.
- 후위 함수의 반환으로 인해서 생기는 임시객체를 const 객체로 생성하겠다는 의미 - 참조자 역시 const 선언해야 함
- 반환형의 const 선언 때문에 (num++)++, (num--)--가 불가능하다.
//멤버함수에서의 후위증가 const Point operator++(int){ const Point retobj(xpos, ypos); xpos += 1; ypos += 1; return retobj }
← 이 부분이 이해가 잘 안되서 직접 돌려보니 다음과 같은 에러가 발생했다.
int main() { int num = 10; cout << ++(++num) << endl; //(O) cout << (num++)++ << endl; //(X) return 0; }
그리고 아래 블로그 글을 읽고 아주 아주 조금 이해했다!
https://hannom.tistory.com/209
자료형이 다른 두 피연산자를 대상으로 하는 연산 - 교환법칙 문제 발생!
: 이 경우 연산의 순서가 바뀌는 형태를 오버로딩해주면 된다.
// Point * int 형을 먼저 정의하고 int * Point형을 오버로딩해주자 Point operator*(int times, Point& ref){ Point pos(ref.xpos * times, ref.ypos * times); return pos; } Point operator*(Point & ref, int times){ return ref * times; }
cout , cin, endl
cout : 객체의 이름으로 <<연산자를 가지고 있다.
// endl이 함수, cout이 객체임을 보여줌! #include <iostream> int main() { using std::cout; using std::endl; endl(cout); return 0; }
<<, >> 연산자의 오버로딩
🙂알고가기
- cout은 ostream 클래스의 객체이다
- ostream은 이름공간 std 안에 선언되어 있으며, 이를 사용하기 위해서는 헤더파일 <iostream>을 포함해야 한다.
Q. 멤버함수 or 전역변수?
A. cout객체에 멤버함수를 추가하는건 불가능하므로 전역함수에 의한 방법을 택할 수 밖에 없다!
class Point{ // public: friend ostream& operator<<(ostream&, const Point&); }; ostream& operator<<(ostream& os, const Point& pos){ os << '[' << pos.xpos<<', '<< pos.ypos << ']' << endl; return os; }
참고로
- cin은 istream 클래스의 객체이다.
- istream은 이름공간 std 안에 선언되어 있으며, 이의 사용을 위해서는 헤더파일 <iostream>을 포함해야 한다.
✔️예시에 나온 fflush를 모르겠어서 찾아보았다.
- fflush 함수 : 버퍼를 비워주는 함수(버퍼에 남아있는 데이터를 출력하고자 하는 곳으로 보냄)
(참고1) https://moolgogiheart.tistory.com/59
- fflush(stdout) / fflush(stdin) : 출력버퍼 / 입력버퍼를 비우는 함수
(참고2) https://moolgogiheart.tistory.com/72
'PROGRAMMING > C++' 카테고리의 다른 글