friend 키워드는 특정 함수나 다른 클래스가 friend가 선언된 클래스의 비공식 및 보호 멤버에 접근할 수 있도록 허용합니다. friend 함수는 전역 함수일 수도 있고 다른 클래스의 메서드일 수도 있습니다. 이러한 구조는 클래스의 내부 상태에 접근할 필요가 있는 함수들을 구현할 수 있게 해주지만, 해당 클래스의 인터페이스와 논리적으로 연결되지 않은 경우에 유용합니다.
friend를 사용하는 것이 좋습니다:
주의:
예시:
class Box { int width; public: Box(int w): width(w) {} friend void printWidth(const Box &b); }; void printWidth(const Box &b) { std::cout << b.width << std::endl; }
질문: friend 함수가 가상일 수 있나요?
자주 듣는 답변: 네, friend는 함수의 수정자입니다.
올바른 답변: 아니요, friend 함수는 클래스의 멤버가 아니기 때문에 가상일 수 없습니다!
예시:
class Example { friend virtual void foo(); // 컴파일 오류: virtual은 friend에 적용되지 않습니다. };
이야기: 행렬 라이브러리를 설계할 때 모든 산술 연산자를 friend 함수로 만들어 속도를 높였지만, 상수성을 지원하는 것을 잊고 비공식 멤버에 대한 접근을 과도하게 열었습니다. 나중에 다른 함수들이 Matrix의 내부 상태를 아무렇게나 변경하는 문제가 발생했습니다.
이야기: 기업 시스템에서 도우미 클래스들이 서로 friend가 되어 비공식 멤버에 대한 접근을 공유했습니다. 이로 인해 순환 의존성이 발생하여 새로운 기능을 추가할 때마다 모든 관련 클래스들을 변경해야 했습니다. 이후의 리팩토링은 몇 주가 걸렸습니다.
이야기: 비공식 테스트를 위해 테스트 클래스를 프로덕션 클래스에 friend로 만들기로 했습니다. 여러 유닛 테스트 세트가 생기면서 실제로 사용되는 비공식 메서드를 추적하기가 불가능해졌고, 테스트가 내부 구현에 의존하게 되어 코드 유지 관리가 복잡해졌습니다.