일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- implicit conversion
- reference
- 메타테이블
- Effective c++
- 반복자
- UE4
- 오블완
- 다형성
- virtual function
- 예외
- 영화
- lua
- 영화 리뷰
- Vector
- resource management class
- 언리얼
- 상속
- c++
- 티스토리챌린지
- exception
- effective stl
- 스마트 포인터
- 비교 함수 객체
- Smart Pointer
- 참조자
- operator new
- 암시적 변환
- 루아
- 게임
- more effective c++
Archives
- Today
- Total
스토리텔링 개발자
[Effective C++] 23. 비멤버 비프렌드 함수 본문
728x90
항목 23 : 멤버 함수보다는 비멤버 비프렌드 함수와 가까워지자.
멤버 버전 vs 비멤버 버전
- 아래 예시에서 clearEverything과 clearBrowser 중 어떤 것이 나을까?
class WebBrowser
{
public:
...
void clearCache();
void clearHistory();
void removeCookies();
...
void clearEverything(); // 멤버 버전. clearCache, clearHistory, removeCookies를 호출
};
void clearBrowser(WebBrowser& wb) // 비멤버 버전
{
wb.clearCache();
wb.clearHistory();
wb.removeCookies();
}
- 객체 지향 법칙이란?
- 데이터와 그 데이터를 기반으로 동작하는 함수는 한 데 묶여 있어야 하며, 멤버 함수가 더 낫다?
- 하지만 이는 객체 지향 방법의 몰이해 상태에서 나온 제안이다.
- 비교
- clearEverything은 clearBrowser보다 캡슐화 정도에서 오히려 형편없다.
- clearEverything은 공개되지 않은 것들을 활용할 여지가 있기 때문.
- 비멤버 함수가 패키징 유연성(packaging flexibility)이 높다.
- 그래서 컴파일 의존도가 낮으며 WebBrowser의 확장성도 높아질 수 있다.
- clearEverything은 clearBrowser보다 캡슐화 정도에서 오히려 형편없다.
캡슐화
- 캡슐화를 하면 이미 있는 코드를 바꾸더라도 제한된 사용자들밖에 영향을 주지 않는 융통성이 생긴다.
- 캡슐화하면 외부에서 볼 수 없게 된다. 즉, 바꿀 때 필요한 유연성이 커진다는 의미이므로.
- 비멤버 비프렌드 함수는 private 멤버 부분을 접근할 수 있는 함수의 갯수를 늘리지 않으므로 캡슐화 정도가 더 높다고 할 수 있다.
비멤버 함수를 제작할 때 주의점
- 비프렌드(non-friend)함수로 해야 한다.
- 프렌드 함수는 해당 클래스의 멤버 함수가 가진 접근권한과 동일하므로 멤버 함수와 동일하다.
- 함수가 어떤 클래스의 비멤버가 되어야 한다는 건, 그 함수가 다른 클래스의 멤버가 될 수 없다는 뜻은 아니다.
- 아무튼 이 함수가 WebBrowser 클래스의 멤버(혹은 프렌드)가 아니기만 하면 된다.
- private 멤버의 캡슐화에 영향을 주지 않는다는 점이 중요하기 때문이다.
C++로 구현하는 더 자연스러운 방법
- clearBrowser를 비멤버 함수로 두되, WebBrowserStuff와 같은 네임스페이스 안에 두는 방법.
namespace WebBrowserStuff
{
class WebBrowser { ... };
void clearBrowser(WebBrowser& wb);
...
};
네임스페이스를 활용한 헤더 쪼개기
- 클래스와 달리 네임스페이스는 여러 개의 소스파일로 나뉘어 흩어질 수 있다.
- 편의 함수에서는 사용자 수준 이상의 기능을 제공할 수 없다.
- 이를 이용해 기능 별로 헤더를 분리한다.
// Webbrowser.h
namespace WebBrowserStuff
{
class WebBrowser { ... }; // 핵심 기능
...
}
// Webbrowserbookmark.h
namespace WebBrowserStuff
{
... // 즐겨찾기 관련 편의 함수만 포함
}
// Webbrowsercookies.h
namespace WebBrowserStuff
{
... // 쿠키 관련 편의 함수만 포함
}
- 사실 표준 C++ 라이브러리가 이런 구조이다.
- std 네임스페이스에 속한 것들이 기능 별로 수십 개의 헤더로 흩어져 선언되어 있다.
- <vector>, <algorithm>, <memory> 등
- 사용자눈 실제로 사용하는 구성요소에 대해서만 헤더를 포함하여, 컴파일 의존성을 고려할 수 있다.
- 확장이 손쉬워진다
- 해당 네임스페이스에 비멤버 비프렌드 함수를 원하는 만큼 추가해 주기만 하면 그게 확장이다.
728x90
'개발 > Effective C++' 카테고리의 다른 글
[Effective C++] 25. 예외를 던지지 않는 swap 함수 (0) | 2024.06.19 |
---|---|
[Effective C++] 24. 비멤버 함수 구현으로 암시적 변환 지원 (0) | 2024.06.18 |
[Effective C++] 22. 데이터 멤버 확실히 숨기기 (0) | 2024.06.17 |
[Effective C++] 21. 참조자를 리턴하면 안되는 상황 (1) | 2024.06.14 |
[Effective C++] 20. const & 전달하기 (0) | 2024.06.13 |
Comments