Search
Duplicate

7장. 프렌드와 연산자 중복

생성일
2022/04/13 13:52
태그
C++

7장. 프렌드와 연산자 중복

C++ 프렌드

프렌드 함수

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

프렌드로 초대하는 3가지 유형

전역 함수 : 클래스 외부에 선언된 전역 함수
다른 클래스의 멤버 함수 : 다른 클래스의 특정 멤버 함수
다른 클래스 전체 : 다른 클래스의 모든 멤버 함수

프렌트 선언 3 종류

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

연산자 중복

중복의 사례) + 연산자

연산자 중복의 특징

C++ 에 본래 있는 연산자만 중복 가능
피 연산자 타입이 다른 새로운 연산 정의
연산자는 함수 형태로 구현 - 연산자 함수(operator function)
반드시 클래스와 관계를 가진다
피연산자의 개수를 바꿀 수 없다
연산의 우선순위 변경이 안된다
모든 연산자가 중복 가능하진 않다
중복 불가능한 연산자 : - . - .* - :: (범위지정 연산자) - ? : (3항 연산자)

연산자 함수

연산자 함수 구현 방법 2가지
클래스의 멤버 함수로 구현
외부 함수로 구현하고 클래스에 프렌드 함수로 선언
연산자 함수 형식
리턴타입 operator연산자 (매개변수리스트);
+ 와 == 연산자의 작성 사례

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

이항 연산자 중복 : + 연산자

예제) 두 개의 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(); }
C++
복사

== 연산자 중복

예제) 두 개의 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; } //bool Power::operator==(const Power& op2) { // if (kick == op2.kick && punch ==op2.punch) // return true; // else return false; } int main() { Power a(3, 5), b(4, 6); // 2개의 동일한 파워 객체 생성 a.show(); b.show(); if (a == b) cout << "두 파워가 같다." << endl; else cout << "두 파워가 다르다." << endl; }
C++
복사

+= 연산자 중복

예제) 두 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; return *this; // 합한 결과 리턴 } int main() { Power a(3, 5), b(4, 6), c; // 2개의 동일한 파워 객체 생성 a.show(); b.show(); c = a += b; a.show(); c.show(); }
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; return tmp; // 임시 객체 리턴 } int main() { Power a(3, 5), b; a.show(); b.show(); b = a + 2; // 파워 객체와 정수 더하기 a.show(); b.show(); }
C++
복사

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

단항 연산자 중복

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

전위 ++ 연산자 중복

예제) 전위 ++ 연산자 작성
#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; // 전위 ++ 연산자 사용 a.show(); b.show(); }
C++
복사
예제) 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! (); // ! 연산자 함수 선언 }; 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; }
C++
복사

후위 연산자 중복, ++ 연산자

매개변수가 하나 있는 임의의 정수를 써준다
후위 연산과 전위 연산을 구분해주기 위해서
예제) 후위 ++ 연산자 작성
#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가 증가되기 이전 상태를 가짐 }
C++
복사

2 + a 덧셈을 위한 + 연산자 함수 작성

예제) 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; tmp.punch = op1 + op2.punch; // private 속성인 kick, punch 를 접근하도록 하기 위해, 연산자 함수를 friend로 선언해야함 return tmp; // 임식 객체 리턴 } int main() { Power a(3, 5), b; a.show(); b.show(); b = 2 + a; a.show(); b.show(); }
C++
복사

+ 연산자를 외부 프렌드 함수로 구현

예제) 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; tmp.punch = op1.punch + op2.punch; return tmp; // 임식 객체 리턴 } int main() { Power a(3, 5), b(4, 6), c; c = a + b; a.show(); b.show(); c.show(); }
C++
복사

단항 연산자 ++ 를 프렌드로 작성하기

예제) ++ 연산자를 프렌드로 작성한 예
#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; } Power& operator++ (Power& op) { // 전위 ++ 연산자 함수 구현 op.kick++; op.punch++; return op; // 연산 결과 리턴 } Power operator++(Power& op, int x) { Power tmp = op; // 변경하기 전의 op 상태 저장 op.kick++; op.punch++; return tmp; // 변경 이전의 op 리턴 } int main() { Power a(3, 5), b; b = ++a; a.show(); b.show(); b = a++; a.show(); b.show(); }
C++
복사
예제) 참조를 리턴하는 << 연산자 작성
#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 n); // 연산 후 Power 객체의 참조 리턴 }; void Power::show() { cout << "kick = " << kick << ", " << "punch = " << punch << endl; } Power& Power::operator<< (int n) { kick += n; punch += n; return *this; } int main() { Power a(1, 2); a << 3 << 5 << 6; a.show(); }
C++
복사