3.3.1 자료형 안전성
소켓 라이브러리는 자료형 안전성(type safety)에 대해선 처음부터 별다른 고민 없이 구현된 상태이다. 따라서 소켓 기본 자료형과 함수를 객체 지향 형태로 감싸두도록 애플리케이션 수준에서 구현해 두면 유용하다. 또한, 이렇게 해서 특정 소켓 API에 고착되지 않도록 관련 코드를 게임에서 분리할 수 있으므로 훗날 소켓 라이브러리를 다른 네트워킹 라이브러리로 교체하고자 할 때도 도움이 된다. 이 책에서도 여러 구조체와 함수를 래핑(wrapping, 감싸두기)해 두는데, 올바른 API 사용법을 예시하는 한편으로 독자 여러분이 코드 작성에 활용할 수 있는 프레임워크를 보다 자료형 안전성이 확보된 형태로 제공하기 위함이다.
코드 3-2 자료형 안정성이 확보된 SocketAddress 클래스
class SocketAddress { public: SocketAddress(uint32_t inAddress, uint16_t inPort) { GetAsSockAddrIn()->sin_family = AF_INET; GetAsSockAddrIn()->sin_addr.S_un.S_addr = htonl(inAddress); GetAsSockAddrIn()->sin_port = htons(inPort); } SocketAddress(const sockaddr& inSockAddr) { memcpy(&mSockAddr, &inSockAddr, sizeof(sockaddr)); } size_t GetSize() const { return sizeof(sockaddr); } private: sockaddr mSockAddr; sockaddr_in* GetAsSockAddrIn() { return reinterpret_cast<sockaddr_in*>(&mSockAddr); } }; using SocketAddressPtr = shared_ptr<SocketAddress>;