More Effective C++ / Scott Meyers 저, 곽용재 역 / 정보문화사
항목 28 : 스마트포인터
기반으로 정리하려 합니다
스마트 포인터의 심장부라고 말할 수 있는 operator와 operator->함수 입니다. operator 부터 알아보겠습니다 일반적으로 스마트포인터의 operator*는 이렇게 구현합니다
template<class T>
T& SmartPtr<T>::operator*() const
{
"스마트포인터" 처리를 수행합니다;
return *pointee;
}
이함수는 pointee를 초기화하든지 pointee를 유효하게 하는 일을 닥치는 대로 합니다. 이를테면, 지연 방식의 가져오기가 사용되는 상태에서는 pointee가 가리키는 객체를 불러와야 하겠습니다. 어쨌든 일단 pointee가 유효하다고 판정되면 operator* 함수는 스마트 포인터가 가리키는 객체의 참조자를 반환합니다
여기서 이 함수의 반환 타입이 참조자(reference) 라는 점에 주목할 필요가 있습니다 T에서 파생된 클래스의 객체를 가리켜도 문제가 없다는 것이죠 만일 이런 경우에 operator* 함수가 실제로 파생된 클래스 객체의 참조자가 아닌 T객체를 (값으로) 반환해 버리면 T 파생 객체의 데이터를 없어지고 T 객체로 반환이 됩니다(슬라이스 문제)
operator-> 동작도 operator*의 동작과 별반 다르지 않습니다 그런데 operator->에 대한 이야기를 하기전에 이 함수의 호출에 관련된 이상한 의미를 함께 고민해 볼 필요가 있습니다
void editTuple(DBPtr<Tuple>& pt)
{
LogEntry<Tuple> entry(*pt);
do {
ps->displayEditDialog();
} while ( ps->isValid() == false );
}
이 함수는 보다시피 Tuple에 대한 스마트 포인터 객체를 사용하는 함수입니다 ps->displayEditDialog(); 이문장은 컴파일러에 의해 다음과 같이 됩니다 (ps.operator->())->displayEditDialog(); operator->가 반환하는 것이 무엇이든 간에 멤버 지정 연산자(->)를 그것에 대해 적용해도 상관 없어야 한다는 뜻을 담고 있습니다 operator->가 반환할 수 있는 것은 오로지 원시 포인터 아니면 스마트 포인터 객체 중 하나입니다. 일반적인 operator-> 다음과 같이 구현합니다
template<class T>
T* SmartPtr<T>::operator->() const
{
"스마트 포인터" 처리를 합니다
return pointee;
}
이함수는 포인터를 반환하기 때문에 operator->를 통해 호출되는 가상함수가 동적 타입에 잘 맞추어 의도대로 동작합니다 선-후 함수 호출(pre-and post function calls) 이라고 스마트 포인터의 깊은 고찰 편에서 살펴보도록 합시다