[C++] 항목 23: 멤버 함수보다는 비멤버 비프렌드 함수와 더 가까워지자
카테고리: Cpp
태그: Cpp
이 글은 아래의 책을 자세히 정리한 후, 정리한 글을 GPT에게 요약을 요청하여 작성되었습니다.
이펙티브 C++ 제3판, 스콧 마이어스 저자, 곽용재 번역
📦 4. 설계 및 선언
👉🏻 항목 23: 멤버 함수보다는 비멤버 비프렌드 함수와 더 가까워지자
아래와 같이 웹브라우저를 나타내는 클래스가 있다.
class WebBrowser {
public:
void clearCache();
void clearHistory();
void removeCookies();
// clearCache, clearHistory, removeCookies 호출
// 멤버 함수 버전
void clearEverything();
};
// 비멤버 함수 버전
void clearBrowser(WebBrowser& wb) {
wb.clearCache();
wb.clearHistory();
wb.removeCookies();
}
멤버 함수 버전과 비멤버 함수 버전 중 어느 쪽이 더 나을까?
➡️ 비멤버 함수 버전이 더 좋다.
❓ 멤버 함수보다 비멤버 함수가 나은 이유
객체지향적으로 보면 멤버 함수로 보이는 게 더 자연스럽다.
하지만, 객체지향의 핵심 원칙 중 하나는 캡슐화다.
- 캡슐화가 높을수록 → 내부 구현을 자유롭게 바꾸기 쉽다.
- 멤버 함수는 클래스의 public 인터페이스이므로 → 변경 시 영향 범위가 크다.
- 반면, 비멤버 함수는 클래스 외부의 독립적인 구성요소로 → 클래스 내부를 보호하면서 기능을 제공할 수 있다.
즉, 데이터에 접근할 수 있는 코드가 많아질수록 캡슐화 정도는 떨어지고,
반대로 접근 경로를 줄이면 캡슐화가 강화된다.
✅ 비멤버 함수가 적합한 조건
- 클래스 내부 상태를 직접 조작하지 않거나,
- 단지 공개된 인터페이스를 조합하는 기능을 수행할 때
즉, 멤버 함수를 단순히 여러 공개 함수들을 묶는 용도라면, 멤버 함수로 둘 이유가 없다.
⚠️ 주의할 점
- 프렌드 함수는 제외
- 프렌드는 클래스의 private 멤버에도 접근할 수 있어 멤버 함수와 다를 바 없다.
- 캡슐화를 깨기 때문에, 프렌드 함수도 최소화해야 한다.
- 다른 클래스의 멤버 함수로 옮기는 건 OK
WebBrowserUtility
같은 유틸리티 클래스의 멤버 함수로 구현해도 괜찮다.
💡 더 자연스럽게 구성하는 방법
namespace WebBrowser {
class WebBrowser { ... };
void clearBrowser(WebBrowser& wb);
}
-
관련 기능들을 네임스페이스로 그룹화하여
구조적 확장성과 자연스러운 코드 구성을 동시에 만족시킬 수 있다.
📦 파일 분리 구조 예시
위와 같이 네임스페이스를 활용하면, 여러 개의 소스 파일로 기능을 분산시켜 구현할 수 있다.
예를 들어, 웹 브라우저 클래스와 관련된 다양한 기능을
다음처럼 헤더 파일별로 나눌 수 있다:
// "webbrowser.h"
namespace WebBrowserStuff {
class WebBrowser { ... };
... // 핵심 기능 비멤버 함수들
}
// "webbrowserbookmarks.h"
namespace WebBrowserStuff {
class WebBrowser { ... };
... // 즐겨찾기 관련 편의 함수
}
// "webbrowsercookies.h"
namespace WebBrowserStuff {
class WebBrowser { ... };
... // 쿠키 관련 편의 함수
}
- 이렇게 하면 사용자는 필요한 기능만
#include
하면 된다. - 또한, 클래스 내부 코드를 건드리지 않고도 관련 기능을 확장하기 쉬워진다.
- 기능을 독립적인 파일로 나누어두면, 유지보수와 모듈화에도 유리하다.
🧐 정리
- 멤버 함수보다 비멤버 비프렌드 함수를 선호하자.
-
캡슐화가 강화되고, 인터페이스 유연성이 생기며,
기능 분리와 확장성도 더 좋아진다. - 프렌드 함수는 멤버 함수만큼 조심해서 써야 한다.
댓글남기기