C++ 타입 재정의에 관한 문제 질문입니다

윈속으로 소켓 사용하는 간단한 프로그램입니다.
헤더파일은 대략 다음과 같이 작성했습니다.
TCPSocket.h
#pragma once #include "SocketAddress.h" #include "SocketUtil.h" class TCPSocket; using TCPSocketPtr = std::shared_ptr<TCPSocket>; class TCPSocket { private: friend class SocketUtil; SOCKET mSocket; TCPSocket(SOCKET inSocket) : mSocket(inSocket) {} public: TCPSocket(); virtual ~TCPSocket(); // 기타 함수들 };
SocketUtil.h
#pragma once #include "UDPSocket.h" #include "TCPSocket.h" enum SocketAddressFamily { INET = AF_INET, INET6 = AF_INET6 }; class SocketUtil { private: SocketUtil(); public: static void ReportError(std::string msg); static int GetLastError(); static TCPSocketPtr CreateTCPSocket(SocketAddressFamily inFamily); static fd_set * FillSetFromVector(fd_set & setOut, const std::vector<TCPSocketPtr> * socketsIn); virtual ~SocketUtil(); // 기타 함수들 };
문제가 되는 부분은 SocketUtil.h입니다.
CreateTCPSocket과 FillSetFromVector 함수에서 반환 타입과 매개변수로 TCPSocketPtr(TCPSocket.h에 정의된)을 사용하고 있는데, 컴파일하면 각 라인에서 다음과 같은 에러가 발생합니다.
error C3646: 'CreateTCPSocket': 알 수 없는 재정의 지정자입니다.
error C2065: 'TCPSocketPtr': 선언되지 않은 식별자입니다.
TCPSocket.h에 정의된 TCPSocketPtr을 인식하지 못하는 걸로 생각해서 SocketUtil.h에
using TCPSocketPtr = std::shared_ptr<TCPSocketPtr>;
을 추가하니 컴파일이 됩니다.
여기서 질문드리고자 하는 내용은 다음과 같습니다.
1. TCPSocket.h에서 TCPSocketPtr을 정의했고 SocketUtil.h에서 TCPSocket.h를 include했는데도 인식하지 못하는 이유가 무엇인가요?
2. SocketUtil.h에 using TCPSocketPtr을 추가하지 않고도 사용할 수 있는 방법이 있을까요?
3. 간혹, 오류가 발생한 코드(헤더의 선언과 cpp의 구현을)를 주석처리한 후 빌드 -> 주석 해제 후 빌드하면 에러가 감쪽같이 사라지는 경우가 있었습니다(주석 처리 외에 코드 수정 X). 단순한 버그인가요?
자바에 익숙한 상태로 C++을 작성하려니 쉽지 않네요 ㅠㅠ
두 헤더 파일이 서로를 include하는것이
두 헤더 파일이 서로를 include하는것이 문제입니다. include는 파일 내용을 그대로 그 자리에 복사하는 것이니 위와 같은 코드에서 preprocessor가 include를 처리한 후 결과가 어떻게 될지 한 번 생각해보세요. 해결 방법은 TCPSocket.h 가 SocketUtil.h 을 include하지 않으면 됩니다. `friend class SocketUtil` 을 위해서는 전방 선언만 해주시면 됩니다. class TCPSocket; 다음에 class SocketUtil; 를 한 줄 추가해주세요.
댓글 달기