명품 C++ 7장 프렌드와 연산자 중복.

Slides:



Advertisements
Similar presentations
7 장 프렌드와 연산자 중복 1 명품 C++. 친구란 ? 2 우리 집 냉장고 내 침대 우리 집 TV 우리 집 식탁 친구 친구 ? 내 가족의 일원은 아니지만 내 가족과 동일한 권한을 가진 일원으로 인정받은 사람.
Advertisements

윤성우 저 열혈강의 C++ 프로그래밍 개정판 Chapter 01. C 언어 기반의 C++ 1.
3. C++와 객체지향 C++ 코딩 방법 객체 단위로 2 개의 파일 인터페이스 파일 구현파일
Vision System Lab, Sang-Hun Han
명품 C++ 프로그래밍 3장. 클래스와 객체.
명품 C++ 8장 상속.
명품 C++ 4장. 객체 포인터와 객체 배열, 객체의 동적 생성.
Power C++ 제6장 포인터와 문자열.
C++ Espresso 제3장 배열과 포인터.
C++ Espresso 제3장 배열과 포인터.
C++ Espresso 제1장 기초 사항.
C++ Espresso 제2장 제어문과 함수.
강좌명 : C++프로그래밍 (C++ Programming)
Chapter 6 구조체.
실전 프로젝트 2 : 숫자야구 숫자 야구를 구현해보자.
C++ 프로그래밍 년 2학기 전자정보공학대학 컴퓨터공학부.
제6장 객체배열과 벡터 객체 배열을 이해한다. 벡터(vector) 클래스를 사용할 수 있다.
명품 C++ 13장 예외 처리와 C 언어와의 링크 지정.
C++ Exspresso 제5장 클래스의 기초.
8. 객체와 클래스 (기본).
C++ 프로그래밍 년 2학기 전자정보공학대학 컴퓨터공학부.
제12장 다형성과 가상함수 다형성의 개념을 이해한다. 상향 형변환의 개념을 이해한다. 가상 함수의 개념을 이해한다.
C++ Espresso 제9장 다형성.
10장 템플릿과 표준 템플릿 라이브러리(STL)
명품 C++ 8장 상속.
제15장 STL과 람다식 STL의 개념을 이해하고 사용할 수 있다. 람다식을 이해하고 사용할 수 있다.
C++ Espresso 제6장 생성자와 소멸자.
명품 JAVA Essential.
7장 클래스.
명품 C++ 7장 프렌드와 연산자 중복.
18장. 헤더 파일과 구현 파일 01_ 헤더 파일과 구현 파일의 사용.
C++ 프로그래밍 년 2학기 전자정보공학대학 컴퓨터공학부.
Chapter 05. 클래스 완성. chapter 05. 클래스 완성 01. 복사 생성자 복사 생성(Copy Construction) 생성될 때 자신과 같은 타입의 객체를 변수로 받아, 이 객체와 같은 값을 갖는 새로운 객체를 생성하는 것 명시적인 생성 과정뿐만.
C++ Programming: Sample Programs
C ++ 프로그래밍 시작.
정적 멤버 변수/정적 멤버 함수 - friend 함수/클래스 template
C++ Programming: chapter 7 – inheritence
아두이노 프로그래밍 2일차 – Part4 아날로그 키패드 활용하기 강사: 김영준 목원대학교 겸임교수.
스택(Stack) 김진수
17장. 문자열 01_ 문자열 사용의 기본 02_ 문자열의 사용.
Visual Studio 2010 프로젝트 생성하기 PC화면에서 Visual Studio 2010 아이콘을 더블클릭 하거나
명품 C++ 프로그래밍 1장. C++ 시작.
C++ 프로그래밍 년 2학기 전자정보공학대학 컴퓨터공학부.
13. 연산자 오버로딩.
제14장 예외처리와 템플릿 예외 처리의 개요를 학습한다. 예외 처리를 적용할 수 있다. 템플릿의 개념을 이해한다.
컴퓨터 개론 및 실습 Dept. Computer Eng. Hankuk University of Foreign Studies
제5장 생성자와 접근제어 객체 지향 기법을 이해한다. 클래스를 작성할 수 있다. 클래스에서 객체를 생성할 수 있다.
컴퓨터의 기초 제 2강 - 변수와 자료형 , 연산자 2006년 3월 27일.
Ch.1 Iterator Pattern <<interface>> Aggregate +iterator
타입, 연산자 Chapter 5, 6 Kum Deuk Kyu , Ph. D. Spring 2015
가상함수와 추상 클래스.
Chapter 1 C와는 다른 C++. 최호성.
제2장 제어구조와 배열 if-else 문에 대하여 학습한다. 중첩 if-else 문에 대하여 학습한다.
제 12장. 사용자 정의형으로서의 클래스 학기 프로그래밍언어및실습 (C++).
4. 고급변수 사용 : 포인터와 관련하여 메모리 바라보기
루프와 카운트 Looping and counting
멤버 함수인 operator+()가 실행, 또는 전역 함수인 operator+()가 실행 Point p3 = p1+p2; 에서
제8장 포인터와 동적객체 생성 포인터의 개념을 이해한다. 포인터와 관련된 연산을 이해한다.
5. 논리적 자료표현 : 구조체.
3장,4장 발표 서정우.
03. 메모리 관리 C++ 프로그램에서 다룰 수 있는 메모리의 종류
C++ Espresso 제13장 입출력과 파일처리.
포인터와 배열 조 병 규 한 국 교 통 대 학 교 SQ Lab..
Ch16_표준 템플릿 라이브러리.
제 8장. 클래스의 활용 학기 프로그래밍언어및실습 (C++).
10장 템플릿과 표준 템플릿 라이브러리(STL)
캡슐화 (Encapsulation) 두원공과대학 소프트웨어개발과 이 원 주.
실습과제 1번 /* 1. 멤버 변수로 반경 radius를 갖고, 그 값을 모니터에 출력하는
제 1장 프로그래밍 언어 소개 1.1 프로그래밍 언어란 무엇인가 1.2 프로그래밍 언어를 배워야 하는 이유
C++ 언어의 특징
Presentation transcript:

명품 C++ 7장 프렌드와 연산자 중복

친구란? 친구? 내 가족의 일원은 아니지만 내 가족과 동일한 권한을 가진 일원으로 인정받은 사람 우리 집 TV 우리 집 냉장고 내 침대 우리 집 식탁

C++ 프렌드 프렌드 함수 클래스의 멤버 함수가 아닌 외부 함수 friend 키워드로 클래스 내에 선언된 함수 전역 함수 다른 클래스의 멤버 함수 friend 키워드로 클래스 내에 선언된 함수 클래스의 모든 멤버를 접근할 수 있는 권한 부여 프렌드 함수라고 부름 프렌드 선언의 필요성 : cout << …, 2 + person, 클래스의 멤버로 선언하기에는 무리가 있고, 클래스의 모든 멤버를 자유 롭게 접근할 수 있는 일부 외부 함수 작성 시

프렌드로 초대하는 3 가지 유형 프렌드 함수가 되는 3 가지 전역 함수 : 클래스 외부에 선언된 전역 함수 다른 클래스의 멤버 함수 : 다른 클래스의 특정 멤버 함수 다른 클래스 전체 : 다른 클래스의 모든 멤버 함수 전역 함수

프렌드 선언 3 종류 1. 외부 함수 equals()를 Rect 클래스에 프렌드로 선언 class Rect { // Rect 클래스 선언 ... friend bool equals(Rect r, Rect s); }; 2. RectManager 클래스의 equals() 멤버 함수를 Rect 클래스에 프렌드로 선언 class Rect { ............. friend bool RectManager::equals(Rect r, Rect s); }; 3. RectManager 클래스의 모든 멤버 함수를 Rect 클래스에 프렌드로 선언 class Rect { ............. friend RectManager; };

예제 7–1 프렌드 함수 만들기(외부함수) #include <iostream> using namespace std; class Rect; bool equals(Rect r, Rect s); // equals() 함수 선언 class Rect { // Rect 클래스 선언 int width, height; public: Rect(int width, int height) { this->width = width; this->height = height; } friend bool equals(Rect r, Rect s); }; bool equals(Rect r, Rect s) { // 외부 함수 if(r.width == s.width && r.height == s.height) return true; else return false; } int main() { Rect a(3,4), b(4,5); if(equals(a, b)) cout << "equal" << endl; else cout << "not equal" << endl; Rect 클래스가 선언되기 전에 먼저 참조되는 컴파일 오류(forward reference)를 막기 위한 선언문 equals() 함수를 프렌드로 선언 equals() 함수는 private 속성을 가진 width, height에 접근할 수 있다. 객체 a와 b는 서로 다른 크기의 사각형이므로 “not equal” 출력 not equal

예제 7–2 다른 클래스의 멤버 함수를 프렌드로 선언 #include <iostream> using namespace std; class Rect; class RectManager { // RectManager 클래스 선언 public: bool equals(Rect r, Rect s); }; class Rect { // Rect 클래스 선언 int width, height; Rect(int width, int height) { this->width = width; this->height = height; } friend bool RectManager::equals(Rect r, Rect s); bool RectManager::equals(Rect r, Rect s) { if(r.width == s.width && r.height == s.height) return true; else return false; } int main() { Rect a(3,4), b(3,4); RectManager man; if(man.equals(a, b)) cout << "equal" << endl; else cout << "not equal" << endl; Rect 클래스가 선언되기 전에 먼저 참조되는 컴파일 오류(forward reference)를 막기 위한 선언문 RectManager 클래스는 Rect 클래스의 private 자료에 접근이 가능함 RectManager 클래스의 equals() 멤버를 프렌드로 선언 객체 a와 b는 동일한 크기의 사각형이므로 “equal” 출력 equal

예제 7–3 다른 클래스 전체를 프렌드로 선언 #include <iostream> using namespace std; class Rect; class RectManager { // RectManager 클래스 선언 public: bool equals(Rect r, Rect s); void copy(Rect& dest, Rect& src); }; class Rect { // Rect 클래스 선언 int width, height; Rect(int width, int height) { this->width = width; this->height = height; } friend RectManager; bool RectManager::equals(Rect r, Rect s) { // r과 s가 같으면 true 리턴 if(r.width == s.width && r.height == s.height) return true; else return false; } void RectManager::copy(Rect& dest, Rect& src) { // src를 dest에 복사 dest.width = src.width; dest.height = src.height; Rect 클래스가 선언되기 전에 먼저 참조되는 컴파일 오류(forward reference)를 막기 위한 선언문 int main() { Rect a(3,4), b(5,6); RectManager man; man.copy(b, a); // a를 b에 복사한다. if(man.equals(a, b)) cout << "equal" << endl; else cout << "not equal" << endl; } 객체 b의 width, height 값이 a와 같아진다. equal man.copy(b,a)를 통해 객체 b와 a의 크기가 동일하므로 “equal” 출력 RectManager 클래스를 프렌드 함수로 선언

연산자 중복(Operator Overloading) 일상 생활에서의 기호 사용 + 기호의 사례 숫자 더하기 : 2 + 3 = 5 색 혼합 : 빨강 + 파랑 = 보라 생활 : 남자 + 여자 = 결혼 + 기호를 숫자와 물체에 적용, 중복 사용 + 기호를 숫자가 아닌 곳에도 사용 간결한 의미 전달 다형성 C++ 언어에서도 연산자 중복 가능 C++ 언어에 본래부터 있든 연산자에 새로운 의미 정의 높은 프로그램 가독성

연산자 중복의 사례 : + 연산자에 대해 정수 더하기 문자열 합치기 색 섞기 배열 합치기 int a=2, b=3, c; c = a + b; // + 결과는 5. 정수가 피연산자일 때 2와 3을 더하기 string a="C", c; c = a + "++“; // + 결과는 “C++". 문자열이 피연산자일 때 두 개의 문자열 합치기 Color a(BLUE), b(RED), c; c = a + b; // c = VIOLET. a, b의 두 색을 섞은 새로운 Color 객체 c SortedArray a(2,5,9), b(3,7,10), c; c = a + b; // c = {2,3,5,7,9,10}. 정렬된 두 배열을 결합한(merge) 새로운 배열 생성

연산자 중복의 특징 C++에 본래 있는 연산자만 중복 가능 피 연산자 타입이 다른 새로운 연산 정의 3%%5 // 컴파일 오류 6## 7 // 컴파일 오류 피 연산자 타입이 다른 새로운 연산 정의 연산자는 함수 형태로 구현 - 연산자 함수(operator function) 반드시 클래스와 관계를 가짐 피연산자의 개수를 바꿀 수 없음 연산의 우선 순위 변경 안됨 모든 연산자가 중복 가능하지 않음 중복 가능한 연산자 중복 불가능한 연산자

연산자 함수 연산자 함수 구현 방법 2 가지 연산자 함수 형식 1. 클래스의 멤버 함수로 구현 2. 외부 함수로 구현하고 클래스에 프렌드 함수로 선언 연산자 함수 형식 사례 리턴타입 operator 연산자(매개변수리스트); Color a(BLUE), b(RED), c; c = a + b; // a와 b를 더하기 위한 + 연산자 작성 필요 if(a == b) { // a와 b를 비교하기 위한 == 연산자 작성 필요 ... }

+와 == 연산자의 작성 사례 외부 함수로 구현되고 클래스에 프렌드로 선언되는 경우 클래스의 멤버 함수로 작성되는 경우 Color operator + (Color op1, Color op2) { ... } bool operator == (Color op1, Color op2) { class Color { friend Color operator+ (Color op1, Color op2); friend bool operator== (Color op1, Color op2); }; 클래스의 멤버 함수로 작성되는 경우 class Color { ... Color operator+ (Color op2); bool operator== (Color op2); };

연산자 중복 설명에 사용할 클래스 class Power { // 에너지를 표현하는 파워 클래스 int kick; // 발로 차는 힘 int punch; // 주먹으로 치는 힘 public: Power(int kick=0, int punch=0) { this->kick = kick; this->punch = punch; } };

멤버 함수로 이항 연산자 구현

이항 연산자 중복 : + 연산자 c = a + b; c = a . + ( b ); class Power { int kick; 컴파일러에 의한 변환 class Power { int kick; int punch; public: ................. Power operator+ (Power op2); }; 오른쪽 피연산자 b가 op2에 전달 리턴 타입 Power a Power Power::operator+(Power op2) { Power tmp; tmp.kick = this->kick + op2.kick; tmp.punch = this->punch + op2.punch; return tmp; } + 연산자 함수 코드

예제 7-4 두 개의 Power 객체를 더하는 + 연산자 작성 #include <iostream> using namespace std; class Power { int kick; int punch; public: Power(int kick=0, int punch=0) { this->kick = kick; this->punch = punch; } void show(); Power operator+ (Power op2); // + 연산자 함수 선언 }; void Power::show() { cout << "kick=" << kick << ',' << "punch=" << punch << endl; Power Power::operator+(Power op2) { Power tmp; // 임시 객체 생성 tmp.kick = this->kick + op2.kick; // kick 더하기 tmp.punch = this->punch + op2.punch; // punch 더하기 return tmp; // 더한 결과 리턴 int main() { Power a(3,5), b(4,6), c; c = a + b; // 파워 객체 + 연산 a.show(); b.show(); c.show(); } 객체 a의 operator+() 멤버 함수 호출 + 연산자 멤버 함수 구현 kick=3,punch=5 kick=4,punch=6 kick=7,punch=11 객체 a, b, c 순으로 출력

== 연산자 중복 a == b a . == ( b ) class Power { ................. public: 컴파일러에 의한 변환 class Power { ................. public: bool operator== (Power op2); }; 오른쪽 피연산자 b가 op2에 전달 리턴 타입 Power a bool Power::operator==(Power op2) { if(kick==op2.kick && punch==op2.punch) return true; else return false; } == 연산자 함수 코드

예제 7-5 두 개의 Power 객체를 비교하는 == 연산자 작성 #include <iostream> using namespace std; class Power { int kick; int punch; public: Power(int kick=0, int punch=0) { this->kick = kick; this->punch = punch; } void show(); bool operator== (Power op2); // == 연산자 함수 선언 }; void Power::show() { cout << "kick=" << kick << ',' << "punch=" << punch << endl; bool Power::operator==(Power op2) { if(kick==op2.kick && punch==op2.punch) return true; else return false; int main() { Power a(3,5), b(3,5); // 2 개의 동일한 파워 객체 생성 a.show(); b.show(); if(a == b) cout << "두 파워가 같다." << endl; else cout << "두 파워가 같지 않다." << endl; } operator==() 멤버 함수 호출 == 연산자 멤버 함수 구현 kick=3,punch=5 두 파워가 같다.

+= 연산자 중복 c = a += b; c = a . += ( b ); class Power { 컴파일러에 의한 변환 class Power { ................. public: Power operator+= (Power op2); }; 오른쪽 피연산자 b가 op2에 전달 리턴 타입 Power a Power Power::operator+=(Power op2) { kick = kick + op2.kick; punch = punch + op2.punch; return *this; } 주목 += 연산자 함수 코드

예제 7-6 두 Power 객체를 더하는 += 연산자 작성 #include <iostream> using namespace std; class Power { int kick; int punch; public: Power(int kick=0, int punch=0) { this->kick = kick; this->punch = punch; } void show(); Power operator+= (Power op2); // += 연산자 함수 선언 }; void Power::show() { cout << "kick=" << kick << ',' << "punch=" << punch << endl; Power Power::operator+=(Power op2) { kick = kick + op2.kick; // kick 더하기 punch = punch + op2.punch; // punch 더하기 return *this; // 합한 결과 리턴 int main() { Power a(3,5), b(4,6), c; a.show(); b.show(); c = a += b; // 파워 객체 더하기 c.show(); } operator+=() 멤버 함수 호출 += 연산자 멤버 함수 구현 kick=3,punch=5 kick=4,punch=6 kick=7,punch=11 a, b 출력 a+=b 후 a, c 출력

+ 연산자 작성(실습): b = a + 2; #include <iostream> using namespace std; class Power { int kick; int punch; public: Power(int kick=0, int punch=0) { this->kick = kick; this->punch = punch; } void show(); Power operator+ (int op2); // + 연산자 함수 선언 }; void Power::show() { cout << "kick=" << kick << ',' << "punch=" << punch << endl; Power Power::operator+(int op2) { Power tmp; // 임시 객체 생성 tmp.kick = kick + op2; // kick에 op2 더하기 tmp.punch = punch + op2; // punch에 op2 더하기 return tmp; // 임시 객체 리턴 int main() { Power a(3,5), b; a.show(); b.show(); b = a + 2; // 파워 객체와 정수 더하기 } operator+(int) 함수 호출 + 연산자 멤버 함수 구현 kick=3,punch=5 kick=0,punch=0 kick=5,punch=7 a, b 출력 b = a + 2 후 a, b 출력

멤버 함수로 단항 연산자 구현

단항 연산자 중복 단항 연산자 피연산자가 하나 뿐인 연산자 단항 연산자 종류 연산자 중복 방식은 이항 연산자의 경우와 거의 유사함 단항 연산자 종류 전위 연산자(prefix operator) !op, ~op, ++op, --op 후위 연산자(postfix operator) op++, op--

전위 ++ 연산자 중복 ++a a . ++ ( ) x = ++a; class Power { ................. 컴파일러에 의한 변환 class Power { ................. public: Power operator++ ( ); }; 매개 변수 없음 리턴 타입 Power a x = ++a; Power Power::operator++( ) { // kick과 punch는 a의 멤버 kick++; punch++; return *this; // 변경된 객체 자신(객체 a) 리턴 } 전위 ++ 연산자 함수 코드

예제 7-8 전위 ++ 연산자 작성 #include <iostream> using namespace std; class Power { int kick; int punch; public: Power(int kick=0, int punch=0) { this->kick = kick; this->punch = punch; } void show(); Power operator++ (); // 전위 ++ 연산자 함수 선언 }; void Power::show() { cout << "kick=" << kick << ',' << "punch=" << punch << endl; Power Power::operator++() { kick++; punch++; return *this; // 변경된 객체 자신(객체 a) 리턴 int main() { Power a(3,5), b; a.show(); b.show(); b = ++a; // 전위 ++ 연산자 사용 } operator++() 함수 호출 전위 ++ 연산자 멤버 함수 구현 kick=3,punch=5 kick=0,punch=0 kick=4,punch=6 a, b 출력 b = ++a 후 a, b 출력

예제 7-9(실습) Power 클래스에 ! 연산자 작성 !a는 a의 kick, punch 파워가 모두 0이면 true, 아니면 false를 리턴한다. #include <iostream> using namespace std; class Power { int kick; int punch; public: Power(int kick=0, int punch=0) { this->kick = kick; this->punch = punch; } void show(); bool operator! (); // ! 연산자 함수 선언 }; void Power::show() { cout << "kick=" << kick << ',' << "punch=" << punch << endl; bool Power::operator!() { if(kick == 0 && punch == 0) return true; else return false; int main() { Power a(0,0), b(5,5); if(!a) cout << "a의 파워가 0이다.“ << endl; // ! 연산자 호출 else cout << "a의 파워가 0이 아니다." << endl; if(!b) cout << "b의 파워가 0이다." << endl; // ! 연산자 호출 else cout << "b의 파워가 0이 아니다." << endl; } operator!() 함수 호출 a의 파워가 0이다. b의 파워가 0이 아니다. ! 연산자 멤버 함수 구현

후위 연산자 중복, ++ 연산자 a++ a . ++ ( 임의의 정수 ) class Power { 컴파일러에 의한 변환 class Power { ................. public: Power operator ++ (int x ); }; 매개 변수 리턴 타입 객체 a Power Power::operator++(int x) { Power tmp = *this; // 증가 이전 객체 상태 저장 kick++; punch++; return tmp; // 증가 이전의 객체(객체 a) 리턴 } 후위 ++ 연산자 함수 코드

예제 7-10 후위 ++ 연산자 작성 ##include <iostream> using namespace std; class Power { int kick; int punch; public: Power(int kick=0, int punch=0) { this->kick = kick; this->punch = punch; } void show(); Power operator++ (int x); // 후위 ++ 연산자 함수 선언 }; void Power::show() { cout << "kick=" << kick << ',' << "punch=" << punch << endl; Power Power::operator++(int x) { Power tmp = *this; // 증가 이전 객체 상태를 저장 kick++; punch++; return tmp; // 증가 이전 객체 상태 리턴 int main() { Power a(3,5), b; a.show(); b.show(); b = a++; // 후위 ++ 연산자 사용 a.show(); // a의 파워는 1 증가됨 b.show(); // b는 a가 증가되기 이전 상태를 가짐 } operator++(int) 함수 호출 후위 ++ 연산자 멤버 함수 구현 kick=3,punch=5 kick=0,punch=0 kick=4,punch=6 a, b 출력 b = a++ 후 a, b 출력

2 + a 덧셈을 위한 + 연산자 함수 작성 b = 2 + a; b = + ( 2 , a ); 객체가 아님! 멤버함수로 불가  변환 불가능 c = 2 . + ( a ); Power a(3,4), b; b = 2 + a; b = 2 + a;  변환 가능 c = + ( 2 , a ); 외부 연산자 함수명 왼쪽 피연산자 오른쪽 피연산자 b = 2 + a; b = + ( 2 , a ); 컴파일러에 의한 변환 매개변수 Power operator+ (int op1, Power op2) { Power tmp; tmp.kick = op1 + op2.kick; tmp.punch = op1 + op2.punch; return tmp; } 리턴 타입

예제 7-11 2+a를 위한 + 연산자 함수를 프렌드로 작성 #include <iostream> using namespace std; class Power { int kick; int punch; public: Power(int kick=0, int punch=0) { this->kick = kick; this->punch = punch; } void show(); friend Power operator+(int op1, Power op2); // 프렌드 선언 }; void Power::show() { cout << "kick=" << kick << ',' << "punch=" << punch << endl; Power operator+(int op1, Power op2) { Power tmp; // 임시 객체 생성 tmp.kick = op1 + op2.kick; // kick 더하기 tmp.punch = op1 + op2.punch; // punch 더하기 return tmp; // 임시 객체 리턴 int main() { Power a(3,5), b; a.show(); b.show(); b = 2 + a; // 파워 객체 더하기 연산 } operator+(2, a) 함수 호출 + 연산자 함수를 외부 함수로 구현 kick=3,punch=5 kick=0,punch=0 kick=5,punch=7 a, b 출력 b = 2+a 후 a, b 출력 private 속성인 kick, punch를 접근하도록 하기 위해, 연산자 함수를 friend로 선언해야 함

+ 연산자를 외부 함수로 구현 c = a + b; c = + ( a , b ); 컴파일러에 의한 변환 매개변수 Power operator+ (Power op1, Power op2) { Power tmp; tmp.kick = op1.kick + op2.kick; tmp.punch = op1.punch + op2.punch; return tmp; } 리턴 타입

예제 7-12 a+b를 위한 연산자 함수를 프렌드로 작성 #include <iostream> using namespace std; class Power { int kick; int punch; public: Power(int kick=0, int punch=0) { this->kick = kick; this->punch = punch; } void show(); friend Power operator+(Power op1, Power op2); // 프렌드 선언 }; void Power::show() { cout << "kick=" << kick << ',' << "punch=" << punch << endl; Power operator+(Power op1, Power op2) { Power tmp; // 임시 객체 생성 tmp.kick = op1.kick + op2.kick; // kick 더하기 tmp.punch = op1.punch + op2.punch; // punch 더하기 return tmp; // 임시 객체 리턴 int main() { Power a(3,5), b(4,6), c; c = a + b; // 파워 객체 + 연산 a.show(); b.show(); c.show(); } + 연산자 함수 구현 operator+(a,b) 함수 호출 kick=3,punch=5 kick=4,punch=6 kick=7,punch=11 객체 a, b, c 순으로 출력

단항 연산자 ++를 프렌드로 작성하기 ++a ++ ( a ) a++ ++ ( a, 0 ) (a) 전위 연산자 컴파일러에 의한 변환 Power operator++ (Power& op) { op.kick++; op.punch++; return op; } 리턴 타입 0은 의미 없는 값으로 전위 연산자와 구분하기 위함 a++ ++ ( a, 0 ) (b) 후위 연산자 컴파일러에 의한 변환 Power operator++ (Power& op, int x) { Power tmp = op; op.kick++; op.punch++; return tmp; } 리턴 타입

예제 7-13 ++연산자를 프렌드로 작성한 예 Power operator++(Power& op) { // 전위 ++ 연산자 함수 구현 op.kick++; op.punch++; return op; // 연산 결과 리턴 } Power operator++(Power& op, int x) { // 후위 ++ 연산자 함수 구현 Power tmp = op; // 변경하기 전의 op 상태 저장 return tmp; // 변경 이전의 op 리턴 int main() { Power a(3,5), b; b = ++a; // 전위 ++ 연산자 a.show(); b.show(); b = a++; // 후위 ++ 연산자 참조 매개 변수 사용에 주목 참조 매개 변수 사용에 주목 #include <iostream> using namespace std; class Power { int kick; int punch; public: Power(int kick=0, int punch=0) { this->kick = kick; this->punch = punch; } void show(); friend Power operator++(Power& op); // 전위 ++ 연산자 함수 프렌드 선언 friend Power operator++(Power& op, int x); // 후위 ++ 연산자 함수 프렌드 선언 }; void Power::show() { cout << "kick=" << kick << ',' << "punch=" << punch << endl; } kick=4,punch=6 kick=5,punch=7 b = ++a 실행 후 a, b 출력 b = a++ 실행 후 a, b 출력

<< 연산자의 중복

<<과 >> 연산자 중복 연산을 수행한 후에 다시 스트림 객체를 반환 하여야 함

주의할 점 전역 함수 형태만 사용 가능: 우리가 ostream 클래스를 다시 정의할 수 없다.

<< 연산자의 중복

<< 연산자의 중복

>> 연산자의 중복 입력 연산자 >>의 중복 오류 처리를 하는 것이 좋음

= 연산자 중복

얕은 대입 문제 동적 할당 공간이 있으면 반드시 = 연산자를 중복 정의하여야 함

얕은 대입 문제 동적 할당 공간이 있으면 반드시 = 연산자를 중복 정의하여야 함

실습문제(7장) p.356 Book 클래스가 다음과 같이 정의된다. class Book { string title; int price; int pages; public: Book(string title="", int price=0, int pages=0) { this->title = title; this->price = price; this->pages = pages; } void show() { cout << title << ' ' << price << "원 " <<pages << " 페이지" << endl; string getTitle() { return title; } };

Book 객체에 대해 다음 연산을 수행하고자 한다. int main() { Book a("청춘", 20000, 300); Book b("미래", 30000, 500); a += 500; // 책 a의 가격 500원 증가 b -= 500; // 책 b의 가격 500원 감소 a.show(); b.show(); }

+=, -= 연산자 함수를 Book 클래스의 멤버 함수로 구현하시오.

2. Book 객체를 활용하는 사례이다. int main() { Book a("명품 C++", 30000, 500), b("고품 C++", 30000, 500); if(a == 30000) cout << "정가 30000원" << endl; // price 비교 if(a == "명품 C++") cout << "명품 C++ 입니다." << endl; // 책 title 비교 if(a == b) cout << "두 책이 같은 책입니다." << endl; // title, price, pages 모두 비교 }

세 개의 == 연산자 함수를 가진 Book 클래 스를 작성하시오. (멤버함수 이용) 세 개의 == 연산자 함수를 프렌드 함수로 작 성하시오.

3. 다음 연산을 통해 공짜 책인지 판별하는 ! 연 산자 함수를 작성하시오. int main() { Book book("벼룩시장", 0, 50); // 가격은 0 if(!book) cout << "공짜다" << endl; }

4. 다음 연산을 통해 책의 제목을 사전순으로 비 교하고자 한다. < 연산자 함수를 작성하라. int main() { Book a("청춘", 20000, 300); string b; cout << "책 이름을 입력하세요>>"; getline(cin, b); if(b < a) cout << a.getTitle() << "이 " << b << "보다 뒤에 있구나!" << endl; }

7. Circle 클래스의 전증가++, 후증가 ++ class Circle { int radius; public: Circle(int radius = 0) { this->radius = radius; } void show() { cout << "radius = " << radius << " 인 원" << endl; } };

다음 연산이 가능하게 연산자 ++를 프렌드로 작성하시오. int main() { Circle a(5), b(4); ++a; // 반지름을 1 증가 시킨다. b = a++; // 반지름을 1 증가 시킨다. a.show(); b.show(); }

8. Circle 클래스에 정수+객체 int main() { Circle a(5), b(4); b = 1 + a; a.show(); b.show(); }