c++ 친구 함수와 클래스 friend
#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 함수를 정의하면 아무런 문제가 없습니다.
'C++ > c++ - 따라하며 배우는 c++' 카테고리의 다른 글
c++ 단항 연산자 오버로딩 하기 (0) | 2020.11.05 |
---|---|
c++ 익명 객체 (anonymous) (0) | 2020.10.30 |
c++ static member function (정적 멤버 함수) (0) | 2020.10.29 |
c++ static member 변수 (0) | 2020.10.29 |
c++ class 와 const (0) | 2020.10.28 |
댓글
이 글 공유하기
다른 글
-
c++ 단항 연산자 오버로딩 하기
c++ 단항 연산자 오버로딩 하기
2020.11.05 -
c++ 익명 객체 (anonymous)
c++ 익명 객체 (anonymous)
2020.10.30 -
c++ static member function (정적 멤버 함수)
c++ static member function (정적 멤버 함수)
2020.10.29 -
c++ static member 변수
c++ static member 변수
2020.10.29
댓글을 사용할 수 없습니다.