본문 바로가기

C++

[C++] friend 함수와 friend 클래스

friend 예약어를 함수나 클래스 선언 앞에 사용할 수 있다. 단, 반드시 클래스 내부에서 선언되어야 한다.

상속이 상하인 수직관계라 한다면 friend를 사용하면 수평관계이다. friend로 선언한 함수나 클래스는 접근 제어 지시자의 영향을 받지 않는다.

 

friend 함수 예)

 

#include <iostream>
using namespace std;

class myClass
{
public:
	myClass(int param) : num(param) {}
	int getNum() const { return num; }
	void setNum(int param) { num = param; }

	//friend 함수 선언
	friend void printNum(const myClass&);

private:
	int num = 0;
};

void printNum(const myClass& a)
{
	//printNum() 함수는 friend 함수이므로 private 접근가능
	cout << "num : " << a.num << endl;
}

int main() {

	myClass a(10);
	printNum(a);

	return 0;
}

 

결과값:

num : 10

 

num은 myClass 안에 private 접근 제어 지시자로 선언하였지만 myClass 안에 friend 함수로 printNum() 함수를 선언하여 myClass와 printNum() 함수는 수평관계가 되었다. 즉, printNum()함수는 myClass의 접근 제어 지시자의 영향을 받지 않아 private로 선언한 num 멤버에 접근이 가능하다.

 

 

다음은 friend 클래스의 예이다.

 

#include <iostream>
using namespace std;

class Tv
{
public:
	Tv(int vol, int ch) : vol(vol), ch(ch){}

	void volUp() { ++vol; }

	friend class Remote;

private:
	int vol, ch;
};

class Remote
{
public:
	//private인 vol멤버에 접근하여 write
	void volUp(Tv& tv) { ++tv.vol; }
	
	//private인 vol멤버에 접근하여 출력
	void printState(Tv& tv) {
		cout << tv.vol << endl;
	}
};


int main() {

	Tv tv(5, 10);
	Remote remote;

	remote.volUp(tv);
	remote.printState(tv);

	return 0;
}

 

결과값:

6

 

Tv 클래스에 Remote와 friend관계임을 명시했다. 이제 Remote 클래스는 Tv 클래스의 private 멤버에 접근이 가능하다.

 

friend는 왜 사용할까? 사용 이유는 뭘까?

답은 관계와 설계인 것 같다. 상속 같은 수직관계가 아니라 수평관계이며 이는 설계할 때 고려할 요소인 것 같다.

위 Tv와 Remote를 보면 Tv는 Remote가 아니고 Remote 역시 Tv가 아니다. 그러나 Tv는 자체 버튼을 통해 볼륨과 채널을 조절할 수 있고 리모컨이라는 물체를 통해서도 가능하도록 설계하고 싶다면 이 둘은 적어도 수직관계는 아닐 것이다. (*주관적 견해입니다.)

 

friend는 잘 사용하지 않는 문법이라고 한다. 그냥 참고만 해야 할 것 같다.