KoreanFoodie's Study
Effective C++ | 항목 15 : 자원 관리 클래스에서 관리되는 자원은 외부에서 접근할 수 있도록 하자 본문
Tutorials/C++ : Advanced
Effective C++ | 항목 15 : 자원 관리 클래스에서 관리되는 자원은 외부에서 접근할 수 있도록 하자
GoldGiver 2022. 10. 25. 16:10
C++ 프로그래머의 필독서이자 바이블인, 스콧 마이어스의 Modern Effective C++ 를 읽고 기억할 내용을 요약하고 있습니다. 꼭 읽어보시길 추천드립니다!
항목 15 : 자원 관리 클래스에서 관리되는 자원은 외부에서 접근할 수 있도록 하자
핵심 :
1. 실제 자원을 직접 접근해야 하는 기존 API 들도 많기 때문에, RAII 클래스를 만들 때는 그 클래스가 관리하는 자원을 얻을 수 있는 방법을 열어 주어야 한다.
2. 자원 접근은 명시적 변환 혹은 암시적 변환을 통해 가능하다. 안전성만 따지면 명시적 변환이 대체적으로 더 낫지만, 고객 편의성을 놓고 보면 암시적 변환이 괜찮다.
다음의 경우처럼, RAII 클래스의 객체를 그 객제가 감싸고 있는 실제 자원으로 변환해야 하는 경우가 종종 생긴다.
std::shared_ptr<Investment> pInv(CreateInvestment());
// 투자금이 유입된 이후로 경과된 날수를 구하는 함수
int daysHeld(const Investment *pi);
...
// 에러! *Investment 가 들어가야 함!
int days = daysHeld(pInv);
// 명시적 변환! pInv 의 실제 포인터를 넘김
int days = daysHeld(pInv.get());
// 암시적 변환! pInv 의 실제 포인터를 넘김
int days = daysHeld(*pInv);
/* 또 다른 예시 */
// 팩토리 함수
Investment* createInvestment();
// shared_ptr 로 자원 관리
std::shared_ptr<Investment> pi1(createInvestment());
// operator -> 를 사용하여 자원에 접근
bool taxable1 = !(pi1->isTaxFree());
// unique_ptr 로 자원 관리
std::unique_ptr<Investment> pi2(createInvestment());
// operator* 를 써서 자원에 접근
bool taxable2 = !((*pi2).isTaxFree());
그렇다면 명시적 변환이 좋을까, 암시적 변환이 좋을까? 다음 예시를 보자.
// C API 에서 가져온 함수들
FontHandle getFont();
void releaseFont(FontHandle fh);
// RAII 클래스
class Font
{
public:
// 자원획득 (값에 의한 전달)
explicit Font(FontHandle fh)
: f(fh)
{}
~Font() { releaseFont(f); }
// 1. 명시적 변환 함수
FontHandle get() { return f; }
// 2. 암시적 변환 함수
operator FontHandle() const { return f; }
private:
// 실제 폰트 자원
FontHandle f;
};
void changeFontSize(FontHandle f, int newSize);
int main()
{
// 실제 Font 클래스 사용 예시
Font f(getFont());
int newFontSize;
// 1. 명시적 변환 함수 사용
changeFontSize(f.get(), newFontSize);
// 2. 암시적 변환 함수 사용
changeFontSize(f, newFontSize);
Font f1(getFont());
// 헉! 원래 의도는 Font 객체를 복사하는 것이었는데,
// f1 이 FontHandle 로 바뀌고 나서 복사되었다! (암시적 변환)
FontHandle f2 = f1;
}
위의 예시처럼, 암시적 변환을 쓰면 get( ) 같은 메소드를 추가로 호출하지 않아도 되어 간편하지만, 실수가 맨 아래의 FontHandle 형 변환의 경우처럼, 의도치 않은 형 변환이 일어날 수 있는 가능성이 있다!
따라서 RAII 클래스를 실제 자원으로 바꾸는 방법으로서 명시적 변환을 제공할 것인지, 암시적 변환을 허용할 것인지에 대한 결정은 그 RAII 클래스만의 특정한 용도와 사용 환경에 따라 달라질 것이다!
'Tutorials > C++ : Advanced' 카테고리의 다른 글
Effective C++ | 항목 17 : new 로 생성한 객체를 스마트 포인터에 저장하는 코드는 별도의 한 문장으로 만들자 (0) | 2022.10.25 |
---|---|
Effective C++ | 항목 16 : new 및 delete 를 사용할 때는 형태를 반드시 맞추자 (0) | 2022.10.25 |
Effective C++ | 항목 14 : 자원 관리 클래스의 복사 동작에 대해 진지하게 고찰하자 (0) | 2022.10.25 |
Effective C++ | 항목 13 : 자원 관리에는 객체가 그만! (0) | 2022.10.25 |
Effective C++ | 항목 12 : 객체의 모든 부분을 빠짐없이 복사하자 (0) | 2022.10.25 |
Comments