Необъявленная ошибка компиляции идентификатора - PullRequest
1 голос
/ 25 января 2012

Я погружаюсь в холодную метель изучения C ++.Я уже знаю Java, но C ++ кажется странным в некоторых вещах.

Вот в чем дело: у меня есть класс A и класс B. У класса A есть экземпляр класса B внутри себя.Класс B должен иметь возможность вызывать некоторые методы класса A, поэтому я помещаю указатель на класс A внутри конструктора класса B и сохраняю его внутри переменной, чтобы я мог получить эти методы с помощью этой переменной.

Здесьмой код (упрощенно):

ClassA.h

#ifndef CLASSA
#define CLASSA

#include "ParentClass.h"
#include "ClassB.h"

class ClassA : public ParentClass {

private:
ClassB *classB;

public:
ClassA(void);
virtual ~ClassA(void);

};
#endif

ClassA.cpp

   #include "ClassA.h"

   //-----------------------------------------------------
   ClassA::ClassA(void){
    classB= new ClassB(this);
   }
   //-----------------------------------------------------
   ClassA::~ClassA(void)
   {
   }
   //-----------------------------------------------------

ClassB.h

#ifndef CLASSB
#define CLASSB

#include "ClassA.h"

class ClassB{

public:
ClassB(ClassA &pClassA){ classA = pClassA; };
ClassA *getClassAInstance(){ return classA; };

private:
ClassA *classA;
};
#endif

ClassB.cpp

#include "ClassA.h"

/*ClassB::ClassB(void){
classA= pClassA;
}*/

Visual Express не выдает ошибок, но когда я компилирую, он говорит, что класс B не распознает, что такое класс A. Что за черт?

1> c: \ xxx \ xxx \ xxx \ xxx \ xxx \ xxx \ xxx \ xxx \ ClassB.h (8): ошибка C2061: синтаксическая ошибка: идентификатор 'ClassA'

1> c: \ xxx\ xxx \ xxx \ xxx \ xxx \ xxx \ xxx \ xxx \ ClassB.h (10): ошибка C2143: синтаксическая ошибка: отсутствует ';'до '*'

1> c: \ xxx \ xxx \ xxx \ xxx \ xxx \ xxx \ xxx \ xxx \ ClassB.h (10): ошибка C4430: отсутствует указатель типа - предполагается int.Примечание: C ++ не поддерживает default-int

1> c: \ xxx \ xxx \ xxx \ xxx \ xxx \ xxx \ xxx \ xxx \ ClassB.h (10): ошибка C4430: отсутствует спецификатор типа -Int предполагается.Примечание: C ++ не поддерживает default-int

1> c: \ xxx \ xxx \ xxx \ xxx \ xxx \ xxx \ xxx \ xxx \ ClassB.h (10): предупреждение C4183: 'getClassAInstance':отсутствует возвращаемый тип;предполагается, что это функция-член, возвращающая 'int'

1> c: \ xxx \ xxx \ xxx \ xxx \ xxx \ xxx \ xxx \ xxx \ ClassB.h (13): ошибка C2143: синтаксическая ошибка:отсутствует ';'перед '*'

1> c: \ xxx \ xxx \ xxx \ xxx \ xxx \ xxx \ xxx \ xxx \ ClassB.h (13): ошибка C4430: отсутствует указатель типа - предполагается int.Примечание: C ++ не поддерживает default-int

1> c: \ xxx \ xxx \ xxx \ xxx \ xxx \ xxx \ xxx \ xxx \ ClassB.h (13): ошибка C4430: отсутствует спецификатор типа -Int предполагается.Примечание: C ++ не поддерживает default-int

1> c: \ xxx \ xxx \ xxx \ xxx \ xxx \ xxx \ xxx \ xxx \ ClassB.h (8): ошибка C2065: 'classA':необъявленный идентификатор

1> c: \ xxx \ xxx \ xxx \ xxx \ xxx \ xxx \ xxx \ xxx \ ClassB.h (8): ошибка C2065: 'pClassA': необъявленный идентификатор

1> c: \ xxx \ xxx \ xxx \ xxx \ xxx \ xxx \ xxx \ xxx \ ClassB.h (10): ошибка C2065: 'classA': необъявленный идентификатор

Необъявленный что?Возвращая int?

необъявленный идентификатор

Почему?Я включил все, верно?Есть идеи, что не так, ребята?

Ответы [ 4 ]

5 голосов
/ 25 января 2012

Это из-за циклической ссылки между вашими заголовочными файлами.Вы можете разбить его, предварительно объявив один из классов внутри заголовка другого, например:

#ifndef CLASSA
#define CLASSA

#include "ParentClass.h"
//#include "ClassB.h" <<<<< Circular reference is now broken

class ClassB; // Added a forward declaration for use below.

class ClassA : public ParentClass {

private:
ClassB *classB;

public:
ClassA(void);
virtual ~ClassA(void);

};
#endif
1 голос
/ 25 января 2012

Вы сделали циклическую зависимость в заголовочных файлах, и они включены в следующем порядке:

  1. ClassA.h
  2. ClassB.h

ClassB не объявляется при использовании в ClassA, поскольку заголовок ClassB.h не будет включен во второй раз (CLASS_B уже был определен ранее).

Добавить

class ClassB;

до определения ClassA.

1 голос
/ 25 января 2012

Включение заголовка class A в class B и заголовка class B в class A формирует циклическую зависимость. Вот почему вы получаете ошибку компилятора. Вместо этого попробуйте использовать Forward Declaration в одном из заголовочных файлов.

ClassB.h

#ifndef CLASSB
#define CLASSB

class ClassA; //forward declaration of ClassA

class ClassB{

public:
ClassB(ClassA* pClassA){ classA = pClassA; };
ClassA *getClassAInstance(){ return classA; };

private:
ClassA *classA;
};
#endif

И включите заголовочный файл ClassA в ClassB.cpp для доступа к реализации ClassA членов.

0 голосов
/ 25 января 2012

Чтобы избежать этого, используйте предварительное объявление в заголовочных файлах, когда это возможно.Это также может значительно сократить время компиляции.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...