본문 바로가기
C,C++

[Effective C++]항목 15 : 자원 관리 클래스에서 관리되는 자원은 외부에서 접근할 수 있도록 하자.

by matters_ 2019. 8. 5.

요약

  • 실제 자원을 직접 접근해야 하는 기존 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 클래스만의 특정한 용도과 사용환경에 따라 다르게 정의되어야 할 것이다.

댓글