MFC 프로그래밍 중에 무척 황당한 경험을 했습니다.
void CTestCRect::OnDraw(CDC* pDC)
{
CRect rect(50, 50, 300, 300);
pDC->DrawText(_T("Test!!"), &rect, DT_WORDBREAK | DT_EDITCONTROL);
rect.MoveToX(200);
pDC->DrawText(_T("Test!!"), rect, DT_WORDBREAK | DT_EDITCONTROL);
}
보통은 이와 같이 사용합니다. 그런데 뭔가 좀 이상하지 않나요?
네, DrawText()를 호출할 때 처음에는 rect의 주소를, 다음에는 그냥 rect를 전달합니다.
전혀 컴파일에 오류도 없고... 둘다 정상 작동합니다.
함수 원형을 살펴보면 CRect를 받는 자리에 LPRECT가 적혀 있는데, LPRECT는 (RECT 구조체의) 포인터입니다.(CRect와 RECT는 호환됩니다.)
그러니까 함수 원형만 놓고 보면 &rect로 전달하는 것이 맞습니다.
그런데 왜 rect로 전달해도 될까요?
그것은 CRect에 LPRECT에 대한 케스팅 연산자가 재정의 되어 있기 때문입니다.
그래서 LPRECT 자리에 CRect를 넣으면 CRect에 정의된 케스팅 연산자가 알아서 CRect의 주소를 반환합니다.MFC 프로그래밍 중에 무척 황당한 경험을 했습니다.
void CTestCRect::OnDraw(CDC* pDC)
{
CRect rect(50, 50, 300, 300);
pDC->DrawText(_T("Test!!"), &rect, DT_WORDBREAK | DT_EDITCONTROL);
rect.MoveToX(200);
pDC->DrawText(_T("Test!!"), rect, DT_WORDBREAK | DT_EDITCONTROL);
}
보통은 이와 같이 사용합니다. 그런데 뭔가 좀 이상하지 않나요?
네, DrawText()를 호출할 때 처음에는 rect의 주소를, 다음에는 그냥 rect를 전달합니다.
전혀 컴파일에 오류도 없고... 둘다 정상 작동합니다.
함수 원형을 살펴보면 CRect를 받는 자리에 LPRECT가 적혀 있는데, LPRECT는 (RECT 구조체의) 포인터입니다.(CRect와 RECT는 호환됩니다.)
그러니까 함수 원형만 놓고 보면 &rect로 전달하는 것이 맞습니다.
그런데 왜 rect로 전달해도 될까요?
그것은 CRect에 LPRECT에 대한 케스팅 연산자가 재정의 되어 있기 때문입니다.
그래서 LPRECT 자리에 CRect를 넣으면 CRect에 정의된 케스팅 연산자가 알아서 CRect의 주소를 반환합니다.
참고:
MSDN - CRect::operator LPRECT()
클레스등에서 타입캐스트연산자 오버로딩
참고:
MSDN - CRect::operator LPRECT()
클레스등에서 타입캐스트연산자 오버로딩