2009-11-30 1 views
1

Еще один вопрос, иди меня! ... Во всяком случае, у меня есть 2 класса с частными конструкторами и статическими функциями, чтобы вернуть экземпляр этого класса. Все было прекрасно, у меня есть main.cpp файл, в котором мне удалось заполучить мой GameState указатель на объект, выполнив:C++: частный конструктор означает отсутствие определения объектов классов внутри заголовков?

gameState *state = gameState::Instance(); 

Но теперь я, кажется, есть проблема. Для удобства я хотел, чтобы и экземпляр gameState, и экземпляр actionHandler сохранили копию указателя друг к другу. Так что я попытался включить в друг друга файлах:

gameState *state; 

и

actionHandler *handler; 

Это, однако, не похоже на работу ... Я получаю «ошибка C2143: синтаксическая ошибка: отсутствует«; ' перед ошибками «*» на обеих этих строках ... Не можете ли вы определить переменные определенной классы в заголовке, если этот класс имеет частный конструктор? Или проблема что-то еще? Или, может быть, это потому, что указатель на экземпляр хранится как статический член?

EDIT: Спасибо, ребята! Удивительно, сколько знаний на C++ я получаю за последние пару дней .. awsome!

ответ

6

Похоже, что вам нужно добавить опережающее объявление противоположного класса в файл заголовка каждого класса. Например:

class actionHandler; 

class gameState 
{ 
private: 
    actionHandler *handler; 

    ... 
}; 

и:

class gameState; 

class actionHandler 
{ 
private: 
    gameState *state; 

    ... 
}; 
+0

Вам не нужно вперед деклараций в обоих заголовки. У вас может быть один '# include' другой. –

+1

Да, но для времени компиляции, если вы можете уйти от него, лучше использовать форвардные объявления, а не включать весь файл класса, где это возможно. – Eclipse

4

Его не потому, что частный конструктор.

Это потому, что у вас есть круговая зависимость. Поэтому, когда вы пытаетесь скомпилировать класс A, вам необходимо скомпилировать класс B, которому требуется скомпилированный класс A и т. Д.

Пробуйте предварительную декларацию.

В заголовочном файле, где GameState определяется

class actionHandler; 
2

Проблема не имеет ничего общего с частными застройщиками. В данной единице перевода (файл .cpp и все включенные файлы .h) компилятор C++ не распознает идентификатор для класса до объявления класса. Это создает проблему, когда два класса содержат элементы, которые ссылаются друг на друга. Решение называется «объявлением вперед», которое является просто именем класса, но без тела. Это может выглядеть примерно так, как это в вашем случае:

== gameState.h ==

... 
// Note no #include for "actionHandler.h" (but there would be in gameState.cpp) 

class actionHandler; 

class gameState 
{ 
    actionHandler *handler; 
    ... 
}; 
... 

== actionHandler.h ==

... 
#include "gameState.h" 

// No forward declaration needed. 

class actionHandler 
{ 
    gameState* state; 
    ... 
}; 
...