728x90
#include <iostream>
using namespace std;

class A
{
private:
	int m_value = 1;
	
};

void doSomething(A& a)
{
	cout << a.m_value << endl;
}

int main()
{

	return 0;
}

 

 

dosomething 이라는 함수가 A라는 class 에 접근해서 m_value 를 출력하고싶을때가 있습니다.

복잡한 프로그래밍을 하다보면 doSomething 함수를 이렇게 구현해야 할때가 있습니다.

특히 연산자 오버로딩에서 friend를 많이씁니다.

 

private 를 public 으로 바꿔주는 방법도 있지만 객체지향의 원칙과는 많이 멀어집니다.

 

A 라는 class 내부에서 doSomething 의 프로토타입을 firend로 선언합니다.

 

 

#include <iostream>
using namespace std;

class A
{
private:
	int m_value = 1;

	friend void doSomething(A& a);
};
void doSomething(A& a)
{
	cout << a.m_value << endl;
}

int main()
{
	A a;
	doSomething(a);
	
	return 0;
}

 

이렇게 하면  private 지만 friend 여서 접근이 가능합니다.

firend 함수는 특정 class의 private member (private 변수) 도 접근이 가능합니다

 

 

다른 두 클래스에서 이름이 같은 member를 호출 하는방법

 

using namespace std;

class B;

class A
{
private:
	int m_value = 1;

	friend void doSomething(A& a, B& b);
};

class B
{
private:
	int m_value = 2;
	friend void doSomething(A& a, B& b);
};

void doSomething(A& a, B& b)
{
	cout << a.m_value << " " << b.m_value <<  endl;
}

int main()
{
	return 0;
}

 

 

class A 에서 friend void doSomething(A& a, B& b); 를 할경우 에러가 납니다.

class B 의 선언이 A 보다 아래에 있기 때문입니다.

이를 해결하기 위해 전방 선언을 합니다.

 

 

class B;

class A
{
private:
	int m_value = 1;

	friend void doSomething(A& a, B& b);
};

 

코드의 가독성은 떨어지지만 복잡한 엔진을 사용할 경우 꼭 사용할 수 밖에 없는 경우가 있습니다.

전방선언 : forward declaration

 

 

외부함수가 아닌 class B 가 class A의 private member 를 접근하고 싶을때

 

#include <iostream>
using namespace std;
class A
{
private:
	int m_value = 1;
};

class B
{
private:
	int m_value = 2;
	void doSomething(A& a)
	{
		cout << a.m_value << endl;
	}
};

int main()
{
	return 0;
}

 

첫번째 방법

 

#include <iostream>
using namespace std;
class A
{
private:
	int m_value = 1;

	friend class B;
};

class B
{
private:
	int m_value = 2;
	
public:
	void doSomething(A& a)
	{
		cout << a.m_value << endl;
	}
};

int main()
{
	A a;
	B b;
	b.doSomething(a);
	return 0;
}

 

class A 에서 b라는 class 를 friend로 선언합니다

그리고 doSomething 함수를 public안으로 넣어줍니다.

 

두번째 방법은 firend member function 으로 class 를 통째로 open 하지않고 특정 함수에 대해서만 open합니다.

 

 

//friend function friend keyword
#include <iostream>
using namespace std;

class A;

class B
{
private:
	int m_value = 2;

public:
	void doSomething(A& a);
};

class A
{
private:
	int m_value = 1;

	friend void B::doSomething(A& a);
};

void B::doSomething(A& a)
{
	cout << a.m_value << endl;
}

int main()
{
	A a;
	B b;
	b.doSomething(a);
	return 0;
}

 

 

이번에 주의해서 보셔야 할점은 class b의 doSomething 함수의 몸체를 class A 밑에 분리 했다는 것입니다.

Class A를 전방선언해서 class B에서 doSomething함수의 class A의 호출의 에러는 막았지만

컴파일 할때 m_value는 찾을수 없다는 에러가 납니다.

 

그래서 class A 함수 밑에서 doSomething 함수를 정의하면 아무런 문제가 없습니다.

728x90