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는 파일 내용을 그대로 그 자리에 복사하는 것이니 위와 같은 코드에서 preprocessor가 include를 처리한 후 결과가 어떻게 될지 한 번 생각해보세요. 해결 방법은 TCPSocket.h 가 SocketUtil.h 을 include하지 않으면 됩니다. `friend class SocketUtil` 을 위해서는 전방 선언만 해주시면 됩니다. class TCPSocket; 다음에 class SocketUtil; 를 한 줄 추가해주세요.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.