C++ Chapter 8.12 : 친구 함수와 클래스

Date:     Updated:

카테고리:

태그:

인프런에 있는 홍정모 교수님의 홍정모의 따라 하며 배우는 C++ 강의를 듣고 정리한 필기입니다. 😀
🌜 [홍정모의 따라 하며 배우는 C++]강의 들으러 가기!


chapter 8. 객체 지향의 기초 : 친구 함수와 클래스

🔔 friend

클래스에서 어떤 함수나 다른 클래스를 friend, 즉 친구로 지정하면 자신의 private 멤버들에도 자유롭게 접근할 수 있게 허락해준다.

  • 함수를 친구로 지정하는 방법
    • firned + 해당 함수의 프로토타입
      friend int getInt(int x);
      
  • 클래스를 친구로 지정하는 방법
    • firned class + 클래스이름
      friend class Something
      
  • 프로토타입 말고 바디까지 붙여도 되긴 하는데 친구로 지정하는 그 시점에선 친구의 내부 변수들을 모를 수도 있기 때문에 대체로 프로토타입만 지정한다.


🔔 일반 함수를 친구로 삼는 경우

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


void doSomething(A& a)
{
    cout << a.m_value << endl; // 👈💥에러!💥
}
  • A 클래스의 멤버 변수 m_valueprivate이기 때문에 void doSomething(A &a) 같은 A 클래스 바깥의 일반 함수에서는 접근할 수 없다.
class A
{
private:
    int m_value = 1;

    friend void doSomething(A& a);  // 친구로 지정
};


void doSomething(A& a)
{
    cout << a.m_value << endl; // 👈 정상 동작.
}
  • A 클래스 내부에서 friend void doSomething(A& a); 이렇게 doSomething 함수를 친구로 지정해주면
    • 이제 doSomething 함수 내에서 A 클래스의 private 멤버들에 접근할 수 있다.

전방 선언

class A
{
private:
    int m_value = 1;

    friend void doSomething(A& a, B& b);  // 👈 💥에러 !!💥
};


class B
{
private:
    int m_value = 1;

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


void doSomething(A& a, B& b)
{
    cout << a.m_value << endl; 
    cout << b.m_value << endl; 
}
  • A 클래스와 B 클래스에서 void doSomething(A& a, B& b) 함수를 친구로 삼으려 한다.
  • void doSomething(A& a, B& b)은 B 타입 객체의 참조를 매개변수로 한다.
  • A 클래스 입장에선 아직 B 클래스가 선언되기 전이기 때문에 doSomething의 매개변수인 B & b 를 보고 B 가 누군지 몰라 에러가 난다.
class B;   // 👈👈 forward declaration

class A
{
private:
    int m_value = 1;

    friend void doSomething(A& a, B& b);   // 정상 작동
};


class B
{
private:
    int m_value = 1;

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


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

이처럼 A 클래스의 선언 위에 class B; 해주면 미리 프로토타입만 전방 선언하여 컴파일러에게 B 클래스라는 것이 있다는 것을 A 클래스 선언 전에 미리 알려줄 수 있다. 따라서 이제 A 클래스의 입장에선 B& b 매개변수를 봐도 B 라는 클래스가 있다는 것을 알기 때문에 문제가 사라진다.


🔔 클래스를 친구로 삼는 경우

A 라는 클래스에서 B 라는 클래스를 통째로 친구 삼으면 B 클래스의 모든 멤버 함수에서 A 의 private 멤버들에도 자유롭게 접근할 수 있게 된다.

class A
{
private:
    int m_value = 1;

    friend class B;   // B 클래스를 친구로 삼음
};


class B   // A 클래스의 모든 private 멤버들을 접근할 수 있다. 
{
private:
    int m_value = 1;

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

    void func_2(A& a)   
    {
        a.m_value++;
    }
};
  • B의 모든 멤버 함수 내에서 A 클래스의 private 멤버 변수인 m_value를 자유롭게 사용할 수 있게 되었다.


🔔 다른 클래스의 특정 멤버 함수만 친구로 삼고 싶을 때

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

A 클래스에서 B 클래스의 멤버 함수 doSomething(A &a) 만 친구로 삼는다면 B 의 멤버 함수 doSomething(A &a) 에서만 A 클래스의 private한 멤버 변수들에 접근할 수 있다.

class A;   // B에서 A를 알아야 하므로 전방 선언

class B
{
private:
	int m_value = 2;

public:
	void doSomething(A& a);  // 친구로 삼으려는 B의 멤버 함수

};

class A 
{
private:
	int m_value = 1;

	friend void B::doSomething(A &a);  // 👈 B의 특정 멤버 함수를 친구로 선언
};

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

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

	return 0;
}


🌜 개인 공부 기록용 블로그입니다. 오류나 틀린 부분이 있을 경우 
언제든지 댓글 혹은 메일로 지적해주시면 감사하겠습니다! 😄

맨 위로 이동하기


Cpp 카테고리 내 다른 글 보러가기

댓글 남기기