Как объявить и определить глобальные переменные, чтобы правильно их получить из всех заголовков/исходных файлов
Ну, я изучаю С++ и никогда не научился делать вещи, которые не являются OO.
Я пытаюсь получить немного больше опыта программирования в стиле C.
GobalInformation.h
#pragma once
#ifndef GLOBALINFORMATION_H
#define GLOBALINFORMATION_H
#include "MapInformation.h"
namespace gi {
MapInformation mapInf;
};
#endif
Я хотел бы иметь доступ к gi:: mapInf из каждого заголовка и cpp в моем проекте. Сейчас я включаю globalinformation.h в каждый заголовок, поэтому я получаю ошибки компоновщика с несколькими определениями.
Как я могу решить проблему?
Ответы
Ответ 1
В файле заголовка делайте
namespace gi {
extern MapInformation mapInf;
};
В CPP файле содержится фактическое определение.
namespace gi {
MapInformation mapInf;
};
Он будет работать так, как вы планируете.
Если вы используете MapInformation для границ библиотек динамической ссылки, вам может потребоваться связать с библиотекой, которая содержит файл cpp определения. Также в окне вам может понадобиться dllimport/dllexport
Ответ 2
Имейте в виду, что наличие глобалов в нескольких единицах компиляции может легко привести к проблемам с порядком инициализации. Вы можете рассмотреть возможность замены каждого глобального на функцию, возвращающую ссылку. В вашем случае поместите это в один файл cpp и объявите его в заголовке:
namespace gi {
MapInformation& getMapInf()
{
static MapInformation result;
return result;
}
}
Ответ 3
Возможно, лучшим решением является создание глобального объекта, который содержит все ваши глобальные данные. Затем передайте умный указатель на классы, которые действительно должны получить доступ к этим общим глобальным данным.
Пример:
class GlobalData
{
public:
int ticks_;
};
//Other file
class ThatNeedsGlobalData
{
public:
ThatNeedsGlobalData(std::shared_ptr<GlobalData> globalData);
};
Это избавит вас от некоторых проблем.
Удачи!
Ответ 4
Глобальными переменными являются C, а пространства имен - С++. Существует хорошая дискуссия об использовании глобальных переменных и о том, как их можно заменить шаблоном Singleton: Globals and Singletons
И вот простой пример: CPP/Classes/Singleton
Ответ 5
Вот несколько вещей, которые вам нужно позаботиться, пытаясь использовать глобальные переменные так, как вы использовали.
-
Убедитесь, что все файлы заголовков, которые содержат файлы заголовков, которые включают GobalInformation.h, также включены внутри #ifndefs. (Я не мог видеть mapinformation.h, поэтому я предполагаю, что вы это сделали)
-
Как и CPP, компилятор C также не обеспечивает порядок инициализации переменных в разных единицах перевода (разные файлы C/CPP).
Следовательно, объявите заголовочный файл как
//GlobalInformation.h
namespace gi {
extern MapInformation mapInf;
};
-
В функции, которая, как вы знаете, будет вызываться, сначала инициализирует переменную. Таким образом, ленивая инициализация также может быть достигнута в C.