다들 아시다시피 최근에 나온 언어나, Visual 도구가 있는 언어에는 왠만하면 거의 property란 게 있습니다.
Property의 간단히 예를 들면

Form1.Caption = "우헤헤헤"
-혹은-
Form1.Caption := '우헤헤헤';

겉보기에는 단순한 할당문이지만, 실제로는 Property 함수를 호출하는 문장입니다.

...문제는 C++에는 Property 같은 것이 없습니다. (Java는 안 해봐서 모르겠지만 없는 것 같습니다 -_-;)
그래서 C++에서는 이렇게 해야 합니다.

Form1->SetCaption(_T("우헤헤헤"));

개인적으로, 위 문장은 확실히 Property를 써서 할당문으로 표현했을 때보다 가독성이 떨어진다고 생각합니다.
그리고 괄호 덕분에 타이핑이 좀 더 귀찮습니다 -_-




어떻게 해야 C++에서 Property 비슷한 것을 구현해볼 수 있을까요?
...다음과 같이 무시무시한 노가다를 해서 일단 구현해볼 순 있습니다.
멤버 초기화 같은 구현에 필요 없는 잡다한 코드는 몽땅 과감히 생략합니다.

[code]
template <class T>
class TCaption {
public:
        TCaption(T *pOwner): m_pOwner(pOwner) { }
        void operator = (LPCTSTR szCaption)
        {
                m_pOwner->SetCaption(szCaption);
        }
        operator LPTSTR ()
        {
                return m_pOwner->GetCaption();
        }

private:
        T *m_pOwner;
        // 속성의 주소를 구하는 것을 막는다. (속성은 진짜 데이터 멤버가 아니라서!)
        void operator & () { }
};

class CForm {
        friend TCaption<CForm>;

public:
        TCaption<CForm> Caption;     // 가짜(?) 속성
        CForm(): Caption(getThis()) { }

private:
        LPTSTR m_Caption;

        void SetCaption(LPCTSTR szCaption)
        {
                m_Caption = const_cast<LPTSTR>(szCaption);
                printf("SetCaption: \"%s\"\n", szCaption);
        }

        LPTSTR GetCaption()
        {
                printf("GetCaption: \"%s\"\n", m_Caption);
                return m_Caption;
        }

        // 초기화 목록에서 this 썼다고 warning 뜨는거 싫어서 -_-
        CForm* getThis() { return this; }
};
[/code]


사용은 이렇게 합니다.

[code]
void main()
{
        CForm Form1;
        LPTSTR temp;

        Form1.Caption = _T("으헤헤헤");
        temp = Form1.Caption;
}
[/code]


...눈 버리는 코드지만 일단 겉보기에는 잘 돌아갑니다.
TCaption이란 클래스를 하나 만들어서 operator = 로 단순한 할당문을 함수 호출로 바꿔주는 부분이 핵심(?)입니다.

결론적으로 그냥 Form1.SetCaption(_T("으헤헤헤")); 를 호출하는 것과 같습니다.

-_-
하지만 물론 속성 하나 추가할 때마다 클래스를 새로 만드는 무서운 일은 하고 싶지 않습니다.
매크로를 만들어서 처리할 순 있겠지만 여튼 이 방법은 이것 저것 문제가 많습니다.



그런데 Visual C++에는 아주 기특한 기능이 하나 있더군요.
물론 Visual C++에서만 되는 기능입니다. (아마 interface 지원을 위해 만들어둔 기능 같습니다.)

위 맛간 코드를 VC++에서 지원하는 기능으로 고쳐서 CForm2를 만들어봤습니다.
[code]
class CForm2 {
public:
        LPTSTR get_Caption()
        {
                printf("CForm2::get_Caption(), ret: \"%s\"\n", m_Caption);
                return m_Caption;
        }

        void put_Caption(LPCTSTR szCaption)
        {
                m_Caption = const_cast<LPTSTR>(szCaption);
                printf("CForm2::put_Caption(\"%s\")\n", m_Caption);
        }

        // 이놈이 바로 핵심.
        __declspec(property(get=get_Caption, put=put_Caption)) LPTSTR Caption;

private:
        LPTSTR m_Caption;
};
[/code]

사용법은 역시 똑같습니다.
[code]
void main()
{
        CForm2 Form2;
        LPTSTR temp;

        Form2.Caption = _T("크히히히");
        temp = Form2.Caption;
}
[/code]


선언문 앞에 __declspec(property( ... ))를 붙여주는 것만으로 깔끔하게 Property처럼 동작합니다.
기특한 점은, get만 적으면 읽기 전용 속성이 되고, put만 적으면 쓰기 전용 속성이 됩니다.
둘 다 적으면? ... 그냥 읽기 쓰기 속성이죠 -_-;

마치 매크로 치환처럼, 대입문이 나왔을 때 L-value면 put 함수를 호출하는 코드로 바꾸고, R-value면 get 함수를 호출하는 코드로 바꾸는것 같습니다.
(그래서 get, put 함수를 private으로 하면 접근할 수 없다고 오류가 납니다 ^^;)

+= 같은 복합 할당 연산자를 쓰면 알아서 get 해서 put 하는 코드로 만들어준다고 하는군요.


MSDN에 있는 내용인데, 배열 속성 기능도 지원한다고 하더군요.

[code]
// 배열 속성 예
__declspec(property(get=get_Pixel, put=put_Pixel)) COLORREF Bitmap[];

p->Bitmap[x][y] = i;    // p->put_Pixel(x, y, i)로 바뀐대요.
i = p->Bitmap[x][y];    // i = p->get_Pixel(x, y)로 바뀐대요.
[/code]


MSDN 설명을 보면 "비정적 가상 데이터 멤버"를 만든다고 되어 있슴다.
아, 그런만큼 당연히 class나 struct 같은 놈들에서만 쓸 수 있습니다.

물론 배열 속성이나 += 같은 것도 연산자를 열심히 오버로드 하면 다 구현할 순 있겠지만요 -_-
여튼 언어의 구조 자체를 바꿔버릴 정도로 강력한 MS 확장에 대한 소개였습니다.