요약
-
실제 자원을 직접 접근해야 하는 기존 API들도 많기 때문에, RAII 클래스를 만들때는 그 클래스가 관리하는 자원을 얻을 수 있는 방법을 열어 주어야 한다.
-
자원 접근은 명시적 변환 혹은 암시적 변환을 통해 가능하다. 안전성만 따지면 명시적 변환이 대체적으로 더 낫지만, 편의성을 놓고 보면 암시적 변환이 괜찮다.
class Investment {//여러 형태의 투자를 모델링한 투자 클래스들의 최상위 클래스
public:
bool isTaxfree() const;
...
};
Investment* createInvestment();//팩토리 함수
std::tr1::shared_ptr<Investment> pi1(createInvestment());//tr1::shared_ptr이 자원관리를 맡도록 합니다..
bool taxable1 = !(pi1->isTaxFree());//operator->를 써서 자원에 접근합니다.
...
std::auto_ptr<Investment> pi2(createInvestment());//auto_ptr로 하여금 자원관리를 맡도록 합니다.
bool taxable2 =!((*pi2).isTaxFree());//operator*를 써서 자원에 접근합니다.
위와 같이 정의된 Investment 클래스에서 pi 스마트 포인터 객체로 하여금 자원에 접근할 수 있도록 한 것처럼 다른 클래스도 클래스 자원에 접근하기 쉽도록 클래스를 짜야한다는 뜻이다.
또한 아래와 같은 클래스에서
FontHandle getFont();
void releaseFont(FontHandle fh);
class Font {
public:
explicit Font(FontHandle fh)
: f(fh)
{}
~Font() {releaseFont(f);}
private:
FontHandle f;
};
아래와 같이 명시적 변환함수를 만들어 자원접근을 할 수 있고
class Font {
public:
...
FontHandle get() const { return f;}//명시적 변환함수
...
};
아래와 같이 FontHandle로의 암시적 변환 함수를 Font에서 제공하도록 할 수도 있다.
class Font {
public:
...
operator FontHandle() const
{ return f; }
...
};
Font F(getFont());
int newFontSize;
...
changeFontSize(f, newFontSize); // Font에서 Fonthandle로 암시적 변환을 수행합니다.
하지만 다음과 같이 실수를 할 가능성이 많아지게 되므로
Font f1(getFont());
...
FontHandle f2 = f1; //원래 의도는 Font 객체를 복사하는 것이었는데, 엉뚱하게도 f1이 FontHandle로 바뀌고 나서 복사되었습니다.
항상 그 RAII 클래스만의 특정한 용도과 사용환경에 따라 다르게 정의되어야 할 것이다.
'C,C++' 카테고리의 다른 글
[C++, STL] <algorithm> std::fill 함수 사용하기 (feat. std::vector, 1차원 배열, 2차원 배열 초기화) (0) | 2019.09.25 |
---|---|
[Effective C++]항목 17 : new로 생성한 객체를 스마트 포인터에 저장하는 코드는 별도의 한 문장으로 만들자. (0) | 2019.08.06 |
[Effective C++] 항목 19 : 클래스 설계는 타입 설계와 똑같이 취급하자. (0) | 2019.08.01 |
[Effective C++] 항목 13 : 자원 관리에는 객체가 그만! (0) | 2019.07.31 |
[Effective C++] 항목 12 : 객체의 모든 부분을 빠짐없이 복사하자. (0) | 2019.07.30 |
댓글