객체지향프로그래밍II(김정준) 중간고사 대비 (7장)
프렌드 함수
class Rect {
...
// 외부 함수 equals()를 Rect 클래스에 프렌드로 선언
friend bool equals(Rect r, Rect s);
// RectManager 클래스의 equals() 멤버 함수를 Rect 클래스에 프렌드로 선언
friend bool RectManager::equals(Rect r, Rect s);
// RectManager 클래스의 모든 멤버 함수를 Rect 클래스에 프렌드로 선언
friend RectManager;
};
- 클래스의 멤버 함수가 아닌 외부 함수
◼ 전역 함수
◼ 다른 클래스의 멤버 함수
◼ 다른 클래스 전체(다른 클래스의 모든 멤버 함수) - friend 키워드로 클래스 내에 선언된 함수
◼ 멤버는 아니지만 멤버 자격을 부여한 함수
◼ 클래스의 모든 멤버를 접근할 수 있는 권한 부여
◼ 클래스 멤버 함수처럼 호출할 수 없음. 원본 호출 방식으로 호출 - 프렌드 선언의 필요성
◼ 클래스의 멤버로 선언하기에는 무리가 있으면서,
◼ 클래스의 모든 멤버를 자유롭게 접근해야 하는 일부 외부 함수 작성 시 필요
class Rect;
bool equals(Rect r, Rect s);
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;
} // friend 함수이기 때문에 private 멤버에 접근 가능
int main() {
Rect a(3, 4), b(4, 5);
if(equals(a, b)) cout << "equal" << endl; // 일반 외부 함수처럼 호출해야 함
else cout << "not equal" << endl;
}
연산자 중복
- C++ 언어에 본래부터 있던 연산자에 새로운 의미 정의(다형성)
- 높은 프로그램 가독성
- operator overloading
- C++에 본래 있는 연산자만 중복 가능
- 3 %% 5 : 컴파일 오류
- 6 ## 7 : 컴파일 오류
- 피 연산자 타입이 다른 새로운 연산 정의
- 연산자는 함수 형태로 구현 - 연산자 함수(operator function)
- a, b가 객체일 때, 컴파일러에 의해 a + b는 a.+(b)로 변환됨(a.add(b))
- 반드시 클래스와 관계를 가짐
- 피연산자의 개수를 바꿀 수 없음
- 연산의 우선 순위 변경 안됨
- 모든 연산자가 중복 가능하지 않음
- ., .*, ::(범위지정 연산자), ? :(삼항 연산자) 는 중복 불가능
// 이후에 연산자 함수 작성에 사용할 클래스
class Power { // 에너지를 표현하는 파워 클래스
int kick; // 발로 차는 힘
int punch; // 주먹으로 치는 힘
public:
Power(int kick=0, int punch=0) {
this->kick = kick;
this->punch = punch;
}
};
- 연산자 함수 구현 방법 2 가지
◼ 클래스의 멤버 함수로 구현
◼ 외부 함수로 구현하고 클래스에 프렌드 함수로 선언
◼ 리턴타입 operator연산자(매개변수리스트);
class Power {
int kick;
int punch;
public:
Power(int kick=0, int punch=0) {
this->kick = kick;
this->punch = punch;
}
Power operator+ (Power op2); // a + b에서 오른쪽 피연산자 b가 op2에 전달됨
Power operator+ (int op2);
// 프렌드 선언 (일반 함수로 호출한 후 private 변수를 사용해야 하기 때문)
// Power + Power도 프렌드로 선언할 수 있지만, 모호성으로 위 함수와 중복 불가
friend Power operator+(int op1, Power op2);
bool operator== (Power op2);
Power& operator+= (Power op2);
Power& operator++ ( ); // 단항 전위 연산자(매개 변수 없음)
Power operator++ (int x); // 단항 후위 연산자
bool operator! (); // !a는 a의 kick, punch가 모두 0일 때 true 리턴
Power& operator<< (int n); // 연결하여 모두 더할 수 있는 특수한 연산자 작성
};
Power Power::operator+ (Power op2) { // c = a + b
Power tmp; // kick과 punch에 각각 연산 수행
tmp.kick = this->kick + op2.kick;
tmp.punch = this->punch + op2.punch;
return tmp;
}
Power Power::operator+(int op2) { // b = a + 2
Power tmp; // kick과 punch에 각각 2를 더함
tmp.kick = kick + op2;
tmp.punch = punch + op2;
return tmp;
}
// b = 2 + a는 b = +(2, a)로 변환되기 때문에 외부 함수로 선언
Power operator+ (int op1, Power op2) { // b = 2 + a
Power tmp;
tmp.kick = op1 + op2.kick;
tmp.punch = op1 + op2.punch;
return tmp;
}
bool Power::operator== (Power op2) { // if( a == b )
if(kick == op2.kick && punch == op2.punch)
return true;
else
return false;
}
Power& Power::operator+=(Power op2) { // b += a or c = a += b
kick = kick + op2.kick;
punch = punch + op2.punch;
return *this;
}
// 프렌드 함수로도 선언 가능 (참조 매개 변수 이용)
Power& Power::operator++() { // b = ++a
kick++;
punch++;
return *this;
}
// 프렌드 함수로도 선언 가능 (참조 매개 변수 이용)
Power Power::operator++(int x) { // b = a++
Power tmp = *this; // 증가 이전 객체 상태 저장
kick++;
punch++;
return tmp; // 증가 이전의 객체(객체 a) 리턴
}
bool Power::operator!() { // if(!a)
if(kick == 0 && punch == 0) return true;
else return false;
}
Power& Power::operator<<(int n) { // a << 3 << 5 (a에 3과 5를 순서대로 더함)
kick += n;
punch += n;
return *this;
}