728x90
황기태 저자의 명품 C++ Programming 개정판을 읽고 학습한 내용을 정리한 포스트입니다!
https://search.shopping.naver.com/book/catalog/32436115747
프렌드
- 클래스 내에 friend 키워드로 선언된 외부 함수를 프렌드 함수(friend function)라고 부르며, 마치 클래스의 멤버인것처럼 클래스의 모든 변수나 함수에 접근 가능하지만 ! 실질적 멤버가 아니므로 상속되지는 않는다.
필요성 & 선언
클래스 멤버 함수로는 적합하지 않지만 private, protected 멤버를 접근해야 하는 특별한 경우, 이 함수를 외부 함수로 작성하고 프렌드로 선언하며, 가장 유용하게 사용되는 대표적인 경우가 연산자 함수이다.
선언하는 방법은 아래 3가지가 있다.
- 클래스 외부에 작성된 함수를 프렌드로 선언
- 다른 클래스의 멤버 함수를 프렌드로 선언
- 다른 클래스의 모든 멤버 함수를 프렌드로 선언
프렌드 함수 선언
class Rect {
....
friend bool equals(Rect r, Rect s); // 함수 equals()를 프렌드 함수로 선언
};
#include <iostream>
using namespace std;
class Rect; // forward decalaration. 이 라인이 없으면, 다음 라인에서 Rect를 참조하는 전방 참조(forward reference) 문제 발생
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; // equals() 함수는 private 속성을 가진 width, height에 접근할 수 있다.
else return false;
}
int main() {
Rect a(3,4), b(4,5);
if(equals(a, b)) cout << "equal" << endl;
else cout << "not equal" << endl;
}
Tip!!! 전방 참조(forward reference) 문제 해결을 위한 전방 선언(forward declaration)
- C++에서는 아래와 같이 변수나 함수, 클래스의 이름을 먼저 선언한 후 그 이름(Identifier)을 참조(사용)하는 backward reference가 원칙
class Rect { // Rect 이름선언
...
};
int main() {
Rect rect; // 선언된 Rect 사용. backward reference
}
- but, 가끔 뒤에서 선언되는 이름을 미리 참조(사용)하는 경우가 발생하는데 이를 전방 참조라 부른다.
- 컴파일러 입장에서는 아직 선언되지 않는 이름을 참조(사용)하므로 forward reference를 컴파일 오류로 처리한다.
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); //프렌드 함수 선언
}; // 컴파일 오류 발생
class Rect; // forward decalaration. 이 라인이 없으면, 다음 라인에서 Rect를 참조하는 전방 참조(forward reference) 문제 발생
bool equals(Rect r, Rect s); // equals() 함수 선언
프렌드 멤버 선언
- 다른 클래스의 멤버 함수를 클래스의 프렌드 함수로 선언 가능
class Rect {
friend bool RectManager::equals(Rect r, Rect s); // RectManager의 equals() 멤버 함수를 프렌드로 초대
};
프렌드 클래스 선언
- 다른 클래스의 모든 멤버 함수를 클래스의 프렌드 함수로 한 번에 선언할 수 잇다.
class Rect {
.....
friend RectManager; // RectManager 클래스의 모든 함수를 프렌드로 초대
};
- RectManager 클래스 전체를 Rect 클래스의 프렌드로 선언하는 사례이다.
- RectManager 클래스에는 두 개의 멤버 함수가 있으며, 이들은 모두 Rect 클래스의 private 멤버를 자유롭게 접근한다.
#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;
public:
Rect(int width, int height) { this->width = width; this->height = height; }
friend RectManager; // 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;
}
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;
}
또한, 프렌드 선언은 클래스 내에 private, public 영역 등 아무 위치에나 가능하다.
728x90
'Programming Language > C++' 카테고리의 다른 글
[C++] 단항 연산자 중복과 프렌드로 구현하기 (2) | 2023.12.06 |
---|---|
[C++] 연산자 중복 (0) | 2023.12.06 |
[C++] static 멤버 (0) | 2023.12.05 |
[C++] 함수 중복 (0) | 2023.12.04 |
[C++] 복사 생성자 (1) | 2023.12.04 |