본문 바로가기
언어/C++

[C++ 기본 공부정리] 15-1. OOP 캡슐화 - 프렌드(friend)

by 민-Zero 2020. 1. 3.

공부 내용을 정리하는 목적 이므로 참고용으로만 읽어 주시기 바랍니다.

틀린 부분에 대한 지적은 감사합니다.

공통의 속성이나 기능, 행동 등을 캡슐에 보관하는 것처럼 하나의 클래스로 묶는 것이 캡슐화라고 앞에서 정리했다. 또한 캡슐화에 속한 개념인 정보은닉을 수행하기 위해 접근 제어자를 사용하여 외부에서 접근할수 있는 클래스의 데이터를 제한하였다. 이번에 정리할 프렌드(friend) 키워드는 접근제어자에 관한 키워드이다.

 

1. friend 란?

private 나 protected로 선언된 객체의 멤버에는 외부에서 직접적인 접근이 불가능하고 해당 객체의 public 멤버함수를 통해서만 접근할 수 있다. 만약 private 멤버에 접근해야 하는 경우가 생겨 그때마다 매번 새로운 public 멤버 함수를 생성해 접근해야 한다면 굉장히 번거롭다. 이러한 경우를 대비해 friend라는 접근 제어 키워드를 제공한다. friend 키워드를 이용한 대상은 해당 객체에 private 와 protected로 선언된 멤버에 접근할 수 있게 된다. 

friend 키워드는 전역 함수, 클래스, 멤버 함수의 세 가지에 적용할 수 있다.

 

문법)

friend 클래스명 or 함수명(필요시 매개 변수 목록); 

 

friend를 적용하고자 하는 함수나 클래스에 friend를 붙여주면 된다. friend를 클래스나 함수에 사용할때 정의에서는 사용하지 않고 원형에서만 사용하여 접근할수 있는 권하는 주는 역할을 한다. friend 키워도를 적용한 클래스나 함수에게 데이터를 공개하도록 해당 클래스에 알려주는 것이므로 private, public, protected 어느곳에서 friend를 적용하여 선언해도 동일한 기능을 수행한다.

 

간단하게 예시를 통해 friend 키워드의 기능을 확인하면 private 멤버만 있는 F_test1에 friend키워드를 F_test2클래스에 적용해 F_test1에 선언해 준다. 그렇다면 F_test1은 F_test2를 friend로 인식해 private로 설정되어 외부에서 접근 불가능한 데이터도 접근가능하도록 허락해 주는것이다. 따라서 F_test2 클래스를 이용해 만든 객체 f2에서 f1의 private 멤버 변수 a의 값을 설정하고 출력 가능하게 되는 것이다.

 

2. friend 클래스

friend키워드를 적용가능한 전역 함수, 클래스, 멤버 함수 3가지 형태중 friend 클래스에 대해 정리하면, 만약 두개의 클래스가 상속관계는 아니지만 서로 연관이 깊어 데이터의 접근을 허용해야 한다면 클래스 자체에 friend 키워드를 적용하여 적용받은 클래스의 모든 멤버 함수가 해당 클래스에 friend 키워드를 적용받은 역할을 하게 된다.

앞에서 사용한 예제가 클래스에 friend를 적용하여 적용된 클래스의 멤버함수 Set 과 PrintInfo 모두 private 멤버 변수에 접근 할 수 있는것을 확인 할 수 있었다.  

 

3. friend 멤버 함수

friend 클래스는 해당 클래스의 모든 멤버 함수가 friend를 적용받았다. 하지만 모든 멤버함수가 friend일 필요가 없는 경우가 더 많을 것이다. 프렌드 멤버 함수는 특정 멤버함수만 friend로 설정하여 필요한 함수에 대해서만 접근을 허용하므로 정보 은닉에 좀더 알맞을 것이다.

멤버 함수에 friend를 적용하여 해당 멤버 함수를 제외하곤 private로 선언된 멤버에 접근이 불가능 하다.

이 friend 멤버 함수를 사용할때 주의할 점은 각 클래스가 서로서로를 참조하고 있기 때문에 해당 클래스나 멤버 변수의 선언을 통해 존재를 먼저 알리지 않으면 컴파일러는 순서대로 코드를 진행하다 해당 클래스나 멤버 함수를 찾을 수 없기 때문에 에러를 발생시킨다. 예를들어 class F_test1을 전방선언으로 클래스의 존재만 먼저 알렸는대 이부분을 지울경우 컴파일러는 F_test2클래스 정의를 만나고 멤버 함수선언 부에서 F_test1을 매개변수로 사용하는것을 만나는대 아직 컴파일러는 F_test1의 존재를 모르기 때문에 에러를 발생시킨다. 

또한 F_test1함수를 전방선언하고 PrintInfo 함수를 F_test2 내부에 정의할경우 F_test1클래스가 존재한다고 전방 선언만 해놨기 때문에 해당 클래스의 멤버는 무엇이 존재하는지 모르기 때문에 F.a로 멤버 변수의 접근이 불가능 하다는 에러를 발생시킨다. 따라서  a 변수를 컴파일러 알 수 있도록 F_test1의 정의가 끝난뒤에 클래스 밖에서 PrintInfo함수를 정의해야한다.

이처럼 클래스가 서로를 참조하는 순환참조의 상황은 문법상 오류가 없는대 컴파일러에서 무엇을 참조해야할지 몰라 오류가 발생할 가능성이 크므로 주의해야 한다.

 

4. friend 전역 함수

클래스나 멤버함수 뿐만 아니라 전역함수에도 적용하여 private로 설정된 멤버 변수에 접근 가능하다. 

 

댓글