나만의 작은 도서관

[TIL][C++] 250430 MMO 서버 개발 8일차: enable_shared_from_this<T>를 사용할때 주의할 점, const_cast의 실제 활용 예시 본문

Today I Learn

[TIL][C++] 250430 MMO 서버 개발 8일차: enable_shared_from_this<T>를 사용할때 주의할 점, const_cast의 실제 활용 예시

pledge24 2025. 5. 1. 00:22
주의사항: 해당 글은 일기와 같은 기록용으로, 다듬지 않은 날것 그대로인 글입니다. 

enable_shared_from_this<T>를 사용할 때 주의할 점

  • enable_shared_from_this는 상속받을 경우, T타입의 this를 스마트 포인터로 사용할 수 있도록 하는 함수 2개를 사용할 수 있게 된다. 여기서 주의할 점은 enable_shared_from_this를 상속받은 클래스를 상속받은 클래스에서 shared_from_this()와 같은 함수를 사용할 때이다.
class Base : public enable_shared_from_this<Base>
{
//...
}

class Derived : public Base
{
//...
}
  • 위 코드에서 Derived는 Base를 상속받았기 때문에 shared_from_this()와 같은 함수를 사용할 수 있다. 하지만 enable_shared_from_this는 Base 타입으로 상속받았기 때문에 Derived에서 shared_from_this()를 그대로 사용하면 Base 타입이 반환된다. 따라서, shared_from_this()를 사용할 때엔 반환 타입을 확인하고 적절하게 캐스팅하여 사용해야 한다.
void Derived::someFunc()
{
	// 잘못된 예시: Base 타입의 shared_ptr이 반환되므로 컴파일 오류 발생
	shared_ptr<Derived> owner = shared_from_this();
	
	// 올바른 에시: 캐스팅 적용(다운 캐스팅. Base* -> Derived*)
	shared_ptr<Derived> owner2 = static_pointer_cast<Derived>(shared_from_this());
}

const_cast의 실제 활용 예시

  • const_cast는 해당 변수의 const 속성을 추가하거나 제거하기 위해 사용하는 캐스팅 방식이다. 좀처럼 쓸 일이 없어 실제로 유용하게 활용될만한 상황을 겪지 못했는데 이번에 겪게 되었다. 상황은 아래와 같다.
void RigisterSend(stirng str)
{
	WSABUF wsaBuf;
	wsaBuf.buf = const_cast<char*>(str.c_str());
	wsaBuf.len = str.length();
	
	::WSASend(...);
}
  • 서버에서 클라이언트로 문자열 데이터를 보내기 위해 WSASend()를 이용하려는 상황이다. WSASend()는 WSABUF 타입의 인자를 요구하는데, WSABUF의 buf 필드는 char* 타입의 버퍼를 요구한다. 문제는 인자로 str로 넘겨줬기 때문에 C스타일의 문자열 타입인 char로 변환해야 하는데 string::c_str() 함수는 반환값이 const char 타입이라는 것이다. 따라서 const 속성을 제거하지 않으면 타입 불일치로 컴파일 오류가 발생하게 된다.
  • 이때, const_cast를 사용하여 const 속성을 제거하면 안전하게 string::c_str()을 사용함과 동시에 const를 제거한 char* 타입을 얻을 수 있게 된다.