티스토리 뷰

728x90

자원관리 클래스에서 관리되는 자원은 외부에서 접근할 수 있도록 하자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 항목 13에서 가져온 예제
void main()
{
    std::tr1::shared_ptr<Investment> pInv(createInvestment());         
    
    // 투자금이 유입된 이후로 경과한 날수   
    int dayHeld(const Investment *pi);      
    
    // 에러
    int days = daysHeld(pInv);     
 
    /*
    daysHeld함수는 Investment * 타입을 원하는데
    std::tr1::shared_ptr<Investment>타입의 객체를 넘기고 있음 
    std::tr1::shared_ptr<Investment>을 Investment *로 변환하고 싶어짐
    */
 
}
cs

 

1
2
3
4
5
6
7
8
9
10
11
//명시적 변환
void main()
{
    //std::tr1::shared_ptr, auto_ptr의 get 멤버 함수
    //명시적 변환을 수행(실제 포인터의 사본을 얻어낼 수 있음)
 
    int days = daysHeld(pInv.get()); 
 
    //pInv에 들어있는 실제 포인터를 daysHeld에 넘김
 
}
cs

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//암시적 변환
class Investment 
{
    public :
        bool isTaxFree() const;
};
 
void main()
{
    Investment * createInvestment(); 
    std::tr1::shared_ptr<Investment> pi1(createInvestment()); 
    
    bool taxable1 = !(pi1->isTaxFree());   // operator ->를 써서 자원에 접근 
    std::auto_ptr<Investment> pi2(createInvestment()); 
    bool taxable2 = !((*pi2).isTaxFree());   // operator*를 써서 자원에 접근
}
 
cs

 

예제 1

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
// C API에서 가져온 함수, 매개변수 생략 
FontHandle getFont();  
 
//C API에서 가져온 함수 
void releaseFont(FontHandle fh); 
 
// RAII 클래스 
class Font 
{  
public:
    explicit Font(FontHandle fh)
                : f(fh) 
            {
 
            } 
            ~Font() 
            { 
                releaseFont(f); 
            } 
private:
    FontHandle f;
};
 
 
 
//Font객체를 FontHandle로 명시적 변환 함수 get() 제공
class Font 
public:
   // 명시적 변환 함수     
    FontHandle get() const 
    {
        return f; 
    }
};
 
// 폰트 API의 일부
void changeFontSize(FontHandle f, int newSize); 
 
void main()
{
    Font f(getFont()); 
 
    int newFontSize; 
 
    //Font에서 FontHandle로 명시적으로 바꾼후 넘김
    changeFontSize(f.get(), newFontSize);
}
 
 
 
//변환 할 때마다 함수를 호출하지 않게 하기 위한 암시적 변환함수 제공
class Font 
public :
    operator FontHandle() const      // 암시적 변환 함수 
             {
                 return f; 
             } 
};
 
void main()
{
    Font f(getFont()); 
    int newFontSize; 
    // Font에서 FontHandle로 암시적 변환 수행
    changeFontSize(f, newFontSize); 
}
 
 
 
//암시적 변환이 들어가면 실수를 저지를 여지가 많아짐.
//Font를 쓰려고 했는데 FontHandle로 바뀔 수도 있음
void main()
{
    Font f1(getFont());
    FontHandle f2 = f1;   // 원래 의도는 Font객체를 복사하는 것이었는데 f1이 FontHandle로 바뀐것이 복사
}
 
 
//std::tr1::shared_ptr은 자원의 엄격한 캡슐화와 느슨한 캡슐화를 동시에 지원함
 
 
 
cs

 

결론

실제 자원을 직접 접근해야 하는 기존 API들도 많기 때문에,
RAII 클래스를 만들 때는 그 클래스가 관리하는 자원을 얻을 수 있는 방법을 열어 주어야 한다.

자원접근은 명시적 변환 혹은 암시적 변환을 통해 가능합니다.
안전성 보다 사용성을 중시하면 암시적(묵시적)변환을 사용해도 되지만 의도적인 결과를 100% 얻기위해서는 명시적 변환을 사용하자.

반응형
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/11   »
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
글 보관함
250x250