C++ 프렌드(Friend)란 무엇인가?
클래스의 프렌드 함수(friend function)는 해당 클래스의 범위(scope) 외부에서 정의되지만, 클래스의 모든 private 멤버와 protected 멤버에 접근할 수 있는 특별한 권한을 지닌 함수입니다. 프렌드 함수의 원형(prototype)이 클래스 정의 내부에 선언되긴 하지만, 프렌드 함수 자체는 그 클래스의 멤버 함수가 아니라는 점에 유의해야 합니다.
프렌드는 일반 함수, 함수 템플릿, 멤버 함수가 될 수 있으며, 클래스나 클래스 템플릿도 프렌드로 지정할 수 있습니다. 어떤 클래스를 프렌드로 선언하면 그 클래스 전체와 해당 클래스의 모든 멤버가 프렌드가 됩니다.
프렌드 선언 방법
함수를 클래스의 프렌드로 선언하려면 클래스 정의 안에서 함수 원형 앞에 friend 키워드를 붙이면 됩니다.
class Box {
double width;
public:
double length;
friend void printWidth( Box box );
void setWidth( double wid );
};ClassTwo의 모든 멤버 함수를 ClassOne의 프렌드로 만들고 싶다면, ClassOne의 정의 안에 다음과 같은 선언을 추가합니다.
friend class ClassTwo;
프렌드 함수 예제
#include <iostream>
using namespace std;
class Box {
double width;
public:
friend void printWidth( Box box );
void setWidth( double wid );
};
// 멤버 함수 정의
void Box::setWidth( double wid ) {
width = wid;
}
// 참고: printWidth()는 어떤 클래스의 멤버 함수도 아닙니다.
void printWidth( Box box ) {
/* printWidth()는 Box의 프렌드이므로
이 클래스의 모든 멤버에 직접 접근할 수 있습니다 */
cout << "Width of box : " << box.width <<endl;
}
// 프로그램의 메인 함수
int main() {
Box box;
// 멤버 함수를 사용해 박스 너비 설정
box.setWidth(10.0);
// 프렌드 함수를 사용해 너비 출력
printWidth( box );
return 0;
}실행 결과
위 코드를 컴파일하고 실행하면 다음과 같은 결과가 출력됩니다.
Width of box: 10
프렌드 함수의 핵심 포인트
출력 결과에서 알 수 있듯이, printWidth()는 Box 클래스의 멤버 함수가 아님에도 불구하고 클래스의 private 멤버 변수 width에 직접 접근할 수 있었습니다.
프렌드 함수와 프렌드 클래스를 활용할 때 기억해야 할 중요한 특징은 다음과 같습니다.
- 멤버 함수가 아님: 프렌드 함수는 객체를 통해 호출하는 것이 아니라 일반 함수처럼 호출됩니다.
- 접근 권한만 부여:
friend선언은 접근 제어(private, protected)를 우회할 수 있는 권한만 부여할 뿐, 상속 관계나 소속 관계를 만들지 않습니다. - 단방향 관계: A가 B의 프렌드라고 해서 B가 자동으로 A의 프렌드가 되지는 않습니다.
- 전이성 없음: A가 B의 프렌드이고 B가 C의 프렌드여도, A가 C의 프렌드가 되는 것은 아닙니다.
- 상속되지 않음: 파생 클래스는 기반 클래스의 프렌드 관계를 물려받지 못합니다.
이러한 특성 때문에 프렌드는 연산자 오버로딩(예: <<, >> 연산자), 두 클래스 간 긴밀한 협업이 필요한 상황 등 특정 경우에 매우 유용하게 활용됩니다. 다만 캡슐화를 약화시킬 수 있으므로 꼭 필요한 경우에만 신중하게 사용하는 것이 좋습니다.