IT

C ++에서 "X는 형식을 지정하지 않습니다"오류

lottoking 2020. 7. 24. 07:24
반응형

C ++에서 "X는 형식을 지정하지 않습니다"오류


다음과 같이 두 개의 클래스가됩니다.

class User
{
public:
  MyMessageBox dataMsgBox;
};

class MyMessageBox
{
public:
  void sendMessage(Message *msg, User *recvr);
  Message receiveMessage();
  vector<Message> *dataMessageList;
};

gcc를 사용하여 다음 오류가 발생합니다.

MyMessageBox는 유형의 이름을 지정하지 않습니다.


컴파일러가 클래스를 확보하고 라인에 User도달 할 수 있습니다. 컴파일러에 대한 아이디어 가 내부 클래스 멤버의 의미를 수 없습니다.MyMessageBoxMyMessageBoxMyMessageBox

멤버로 사용 하기 전에MyMessageBox 정의되어 있는지 확인해야합니다 . 이 정의됩니다. 그러나 주기적 의존성이 있습니다. 위로 이동 하면 이름 정의에 정의되지 않습니다!MyMessageBoxUserMyMessageBoxUser

당신이 할 수있는 일은 앞으로 선언 것입니다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);

  1. 전달 사용자 선언
  2. 사용자 앞에 MyMessageBox 선언을 넣으십시오.

C ++ 컴파일러는 입력을 한 번 처리합니다. 사용하는 각 클래스가 먼저 정의되어 있어야합니다. 당신이 사용하는 MyMessageBox당신이 그것을 정의하기 전에. 이 경우 두 클래스 정의를 간단히 바꿀 수 있습니다.


User가 MyMessageBox의 객체를 값으로 포함하기 때문에 사용자보다 먼저 MyMessageBox를 정의해야 합니다 (따라서 컴파일러는 크기를 알아야합니다).

또한 MyMessageBox에 User * 유형의 멤버가 포함되어 있으므로 MyMessageBox에 대해 사용자 전달 해야 합니다.


관련 메모에서 다음과 같은 경우 :

    class User; // let the compiler know such a class will be defined

    class MyMessageBox
    {
    public:
        User* myUser;
    };

    class User
    {
    public:
        // also ok, since it's now defined
        MyMessageBox dataMsgBox;
    };

그러면 사용자가 MyMessageBox에 포인터로 정의되어 있기 때문에 작동합니다.


사용하기 전에 프로토 타입을 선언해야합니다.

class User;

class MyMessageBox
{
public:
 void sendMessage(Message *msg, User *recvr);
 Message receiveMessage();
 vector<Message> *dataMessageList;
};

class User
{
public:
 MyMessageBox dataMsgBox;
};

편집 : 유형을 바꿨습니다.


C ++에서는 항상 헤더 파일 당 하나의 클래스를 사용하도록 권장 합니다. SO [ 1 ] 의이 토론을 참조하십시오 . GManNickG 답변은 왜 이런 일이 발생하는지 알려줍니다. 그러나이를 해결하는 가장 좋은 방법은 User클래스를 하나의 헤더 파일 ( User.h)에 배치하고 MyMessageBox클래스를 다른 헤더 파일 ( MyMessageBox.h)에 배치하는 것입니다. 그런 다음 당신 User.h이 포함 MyMessageBox.h하고 MyMessageBox.h당신 안에 User.h. 코드가 성공적으로 컴파일되도록 "include gaurds"[ 2 ]를 잊지 마십시오 .

참고 URL : https://stackoverflow.com/questions/2133250/x-does-not-name-a-type-error-in-c

반응형