C ++ stati c экземпляр enum, совместно используемый двумя исходными файлами - PullRequest
0 голосов
/ 09 февраля 2020

Я создаю игру. У меня есть два исходных файла: game. cpp и renderHandler. cpp. У меня есть один заголовочный файл, gameState.h. Файл gameState.h содержит stati c экземпляр перечисления, представляющий различные состояния игры.

Я хочу поделиться этой переменной stati c с двумя исходными файлами. Я не хочу две отдельные переменные в каждом исходном файле. Если я изменю значение переменной состояния игры, я хочу, чтобы она была перенесена в другой исходный файл.

gameState.h

#pragma once
enum State {
    start,
    play,
    stop
} static gameState;

game. cpp

#include "../inc/gameState.h"
void Game::init()
{
    gameState = State::play;
}

renderHandler. cpp

#include "../inc/gameState.h"
void RenderHandler::render()
{
    if (gameState == State::start) {
        // code
    }
    else if (gameState == State::play) {
        // code
    }
    else if (gameState == State::stop) {
        // code
    }
}

Значение gameState изменено в файле игры. cpp. Но это не влияет на значение gameState в renderHandler. cpp, по умолчанию оно равно 0, что мне не нужно. Изменение значения происходит до того, как какой-либо код рендеринга будет выполнен.

Как я могу совместно использовать stati c экземпляр перечисления между двумя исходными файлами? Мой лог c неправильный, и я не должен использовать заголовки и перечисления таким образом?

Ответы [ 3 ]

2 голосов
/ 09 февраля 2020

Не делитесь глобальными значениями напрямую, как это. Вы можете столкнуться с stati c порядком инициализации фиаско , который действительно трудно обнаружить.

Вместо этого используйте функцию:

enum State {
    start,
    play,
    stop
};

inline State& gameState() {
    static State currentState;
    return currentState; // Returns a reference, so you can change the value when you need to
}

game. cpp

#include "../inc/gameState.h"
void Game::init()
{
    gameState() = State::play;
}

renderHandler. cpp

#include "../inc/gameState.h"
void RenderHandler::render()
{
    if (gameState() == State::start) {
        // code
    }
    else if (gameState() == State::play) {
        // code
    }
    else if (gameState() == State::stop) {
        // code
    }
}

Кстати, вы не получаете того, что ожидаете, потому что значение static отличается в глобальной области видимости. Читать stati c против глобальных и Что такое внешняя и внутренняя связь?

0 голосов
/ 09 февраля 2020

"stati c" не имеет никакого значения для глобальных переменных. Вы должны пометить глобальную переменную как "extern" и добавить ее инициализацию в gamestate. cpp

Заголовок: extern State gameState;

Cpp: State gameState = * initial Перечислите значение ;

и добавьте это cpp к компиляции вашего проекта.

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

0 голосов
/ 09 февраля 2020

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

Чтобы использовать один экземпляр, вам нужно либо использовать глобальную переменную (плохо, потому что это затрудняет поддержку кода), использовать синглтон (лучше , но все же его следует избегать, поскольку его также сложно поддерживать), или просто создайте один экземпляр этой переменной состояния в начале вашей программы, а затем предоставьте ссылку на нее в классах, используя ее в своих конструкторах.

...