C++: закрытый конструктор означает отсутствие определения объектов этих классов внутри заголовков?

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

gameState *state = gameState::Instance();

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

gameState *state;

а также

actionHandler *handler;

Однако это, похоже, не работает... Я получаю "ошибку C2143: синтаксическая ошибка: отсутствует ';' до появления ошибок '*' 'в обеих этих строках... Разве вы не можете определить переменные определенного класса в заголовке, если у этого класса есть закрытый конструктор? Или проблема в другом? ИЛИ может быть, потому что указатель на экземпляр хранится как статический член?

РЕДАКТИРОВАТЬ: Спасибо, ребята! Удивительно, сколько знаний о С ++ я получаю за последние пару дней... потрясающе!

3 ответа

Решение

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

class actionHandler;

class gameState
{
private:
    actionHandler *handler;

    ...
};

а также:

class gameState;

class actionHandler
{
private:
    gameState *state;

    ...
};

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

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

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

В заголовочном файле, где определено gameState

class actionHandler;

Проблема не имеет ничего общего с частными конструкторами. В данном модуле перевода (файл.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;
  ...
};
...
Другие вопросы по тегам