2013-10-02 4 views
4

Несколько месяцев назад я создал проект C# для игры под названием Vexed. Теперь я создаю тетрис, но на C++. В основном я хочу использовать ту же логику, что и в другом проекте, это было примерно так:Как объявить статический экземпляр класса в C++?

Я создал класс под названием «Игра», где была вся информация об игре. У него были свои методы, переменные и все такое. Затем я создал статический класс под названием «PublicInstances» или что-то подобное, и в этом классе я объявил что-то вроде этого:

static class PublicInstances 
{ 
    public static Game vexedGame = new Game(); //This is C# and works. 
} 

Он сделал это так просто использовать то, потому что любое изменение я сделал на игру был сохранен в этом статическом экземпляре моего класса, и я мог бы получить к нему доступ в любом месте проекта. Я хочу знать, как делать именно это с C++, чтобы создать общедоступный или глобальный экземпляр моей игры класса, чтобы я мог получить к нему доступ и изменить его повсюду и обновить все в любой форме или классе моего проекта. Я бы очень признателен вам за вашу помощь.

// Извините, если мой английский не является лучшим ^^

+1

если и действительно хотите глобальное, у не должны поставить его в классе. просто объявите его в заголовке и определите в исходном файле. но глобалы (или общедоступная статика) обычно плохие. – Kal

+0

Моя основная проблема заключается в том, что я обычно путешествую между Forms, и мне нужно получать информацию из одного места в другое, как я могу изменить использование глобальной переменной или класса? – avatarbobo

+0

Звучит так, как будто 'TetrisGame' должно быть пространством имен, а не объектом. Это также устранит необходимость определения типа класса для него. –

ответ

3

Revisited и суммированы

Вариант 1

Вы можете просто объявить и определить глобальный экземпляр объекта Game , В файле заголовка, например. game.h:

extern Game globalGameObj; 

Когда вы включаете game.h в исходный файл, имя globalGameObj становится видимым. Вам также необходимо создать реальный объект. В исходном файле, например. game.cc (вне любого класса):

Game globalGameObj; 

Access это имя переменной:

globalGameObj.do_some_work(); 

Вариант 2

Используйте шаблон часто называют синглтон. Добавьте следующую строку в ваш класс Game (game.h):

class Game 
{ 
    public: 
    static Game &shared_instance() {static Game game; return game;} 

    private: 
    // Make constructor private. Only shared_instance() method will create an instance. 
    Game() {/*whatever initialisation you need*/} 
}; 

вас экземпляр доступа игры с методом shared_instance():

Game::shared_instance().go_some_work(); 

Вы не использовать ничего, как ваш static class PublicInstances в выше. C++ позволяет ввести пространство имен (например, PublicInstances), чтобы обеспечить изоляцию имен и сохранить ваши глобальные объекты в одном месте, но это, вероятно, будет излишним. В любом случае, если у вас мало глобальных объектов, это, вероятно, плохой дизайн.

Какой вариант лучше? Некоторые люди утверждают, что одноэлементная модель должна использоваться. Это гарантирует, что создается только один экземпляр. Однако оба варианта 1 и вариант 2 имеют одинаковую проблему: они вводят глобальный объект в ваш код со всеми недостатками, связанными с глобальными переменными. Я бы сказал, что singleton - это глобальный объект, который скрывается. Я не вижу решения по техническим причинам в пользу любого варианта, поэтому я бы сказал, что это вопрос личного вкуса.

Историческая справка :)

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

static Game *instance() {if (!_inst) _inst = new Game(); return _inst;} 

Мало кто предположил, что это был не лучший способ больше, спасибо Kal, argiopeweb и Simple. C++ 03 имеет проблемы с инициализацией статических объектов в присутствии потоков. C++ 11 гарантирует безопасную инициализацию статики.

C++ 11 проект, secion 6,7

such a variable is initialized the first time control passes through its declaration; 
such a variable is considered initialized upon the completion of its initialization. [...] 
If control enters the declaration concurrently while the variable is being initialized, 
the concurrent execution shall wait for completion of the initialization. 
+1

Не требуется класс. –

+1

Вы объявили 'S :: _ inst', но вы его не определили. – Adam

+0

также лучшим способом для этого является 'static S & instance() {static S inst; return inst; } ' – Kal

Смежные вопросы