컴파일러가 클래스를 컴파일하고 행에 User
도달하면 아직 정의되지 않았습니다. 컴파일러는 존재하지 않기 때문에 클래스 멤버의 의미를 이해할 수 없습니다.MyMessageBox
MyMessageBox
MyMessageBox
멤버로 사용 하기 전에이MyMessageBox
정의되어 있는지 확인해야합니다 . 이것은 정의 순서를 반대로하면 해결됩니다. 그러나 순환 종속성이 있습니다. 위로 이동 하면 이름 의 정의 가 정의되지 않습니다!MyMessageBox
User
MyMessageBox
User
당신이 할 수있는 일은 앞으로 선언하는 것입니다 User
. 즉, 선언하지만 정의하지 마십시오. 컴파일 중에 선언되었지만 정의되지 않은 유형을 불완전한 유형 이라고합니다 . 더 간단한 예를 고려하십시오.
struct foo; // foo is *declared* to be a struct, but that struct is not yet defined
struct bar
{
// this is okay, it's just a pointer;
// we can point to something without knowing how that something is defined
foo* fp;
// likewise, we can form a reference to it
void some_func(foo& fr);
// but this would be an error, as before, because it requires a definition
/* foo fooMember; */
};
struct foo // okay, now define foo!
{
int fooInt;
double fooDouble;
};
void bar::some_func(foo& fr)
{
// now that foo is defined, we can read that reference:
fr.fooInt = 111605;
fr.foDouble = 123.456;
}
앞으로 선언하여 User
, MyMessageBox
여전히 포인터 또는 참조를 형성 할 수 있습니다.
class User; // let the compiler know such a class will be defined
class MyMessageBox
{
public:
// this is ok, no definitions needed yet for User (or Message)
void sendMessage(Message *msg, User *recvr);
Message receiveMessage();
vector<Message>* dataMessageList;
};
class User
{
public:
// also ok, since it's now defined
MyMessageBox dataMsgBox;
};
당신은 할 수없는 약이에게 다른 방법을 수행 언급 한 바와 같이, 클래스 멤버 정의를 가질 필요가있다. (이유는 컴파일러가 얼마나 많은 메모리를 User
차지하는지 알아야하고 멤버의 크기를 알아야한다는 것을 알아야하기 때문입니다.) 다음과 같이 말하면 다음과 같습니다.
class MyMessageBox;
class User
{
public:
// size not available! it's an incomplete type
MyMessageBox dataMsgBox;
};
아직 크기를 모르기 때문에 작동하지 않습니다.
참고로이 기능은 다음과 같습니다.
void sendMessage(Message *msg, User *recvr);
아마도 그것들 중 하나를 포인터로 가져 가서는 안됩니다. 메시지없이 메시지를 보낼 수 없으며 보낼 사용자없이 메시지를 보낼 수 없습니다. 그리고이 두 상황은 매개 변수 중 하나에 인수로 null을 전달하여 표현할 수 있습니다 (null은 완벽하게 유효한 포인터 값입니다!).
대신 참조 (아마도 const)를 사용하십시오.
void sendMessage(const Message& msg, User& recvr);