Страницы

Поиск по вопросам

среда, 29 января 2020 г.

Глобальная переменная с++

#cpp


Подскажите, как реализовать следующее. Есть примерно 8 пар .h и .cpp файлов, в одном
из них есть функция, которая считывает введённые данные. Мне надо запомнить эти данные,
чтобы я мог в остальных файлах ими пользоваться. Как это реализовать? В интернете что-то
нашел про extern, но так и не получилось ничего.
    


Ответы

Ответ 1



Везде, где собираетесь использовать глобальную переменную, включите её декларацию (declaration), например, пусть она будет в каком-то общем хедере. А только в одном из модулей cpp определите эту переменную (definition) File 1: int GlobalVariable; // определение в одном файле. здесь переменная "будет жить" void SomeFunction(); void AnotherFunction(); int main() { GlobalVariable = 1; SomeFunction(); AnotherFunction(); return 0; } File 2: extern int GlobalVariable; // декларация во всех пользующихся файлах void SomeFunction() { ++GlobalVariable; } File 3: extern int GlobalVariable; // декларация во всех пользующихся файлах void AnotherFunction() { --GlobalVariable; }

Ответ 2



Вообще ИМХО, раз уж задачка решается на C++, то лучше сразу проектировать правильно, ибо глобальные переменные - всё-таки зло. ;) А именно сделать следующее: В одном исходнике создать класс, который управляет всем - Manager; В другом реализовать класс, который считывает данные и хранит их - DataReader; В остальных - прочую логику работы, которая реализует всё, что вам нужно. Правильная архитектура решит множество проблем. Пример: file "data_reader.h" struct MyData { // ... мои данные ... int my_field; }; class DataReader { MyData my_data; public: bool ReadData( const std::string& data_file ) { // ... считываем входные данные в my_data ... return true; } // по требованию использующей стороны отдаём данные TMyData& Data() { return my_data; } }; file "manager.h" #include "data_reader.h" #include "mylogic1.h" #include "mylogic2.h" // ... #include "mylogic8.h" #include class Manager { DataReader data_reader; MyLogic1 my_logic1; MyLogic1 my_logic2; // ... MyLogic1 my_logic8; bool init_ok; public: // В конструкторе менеджера сказать всем классам, реализующим мою логику, // откуда брать прочитанные данные Manager(const std::string& data_file) : my_logic1 (data_reader) , my_logic2 (data_reader) // ... , my_logic8 (data_reader) { init_ok = data_reader.ReadData(data_file); } // bool IsInitOk() { return init_ok; } // void Work() { my_logic1.Work(); my_logic2.Work(); // ... my_logic8.Work(); } }; Реализация моей логики "mylogic1.h" #include "data_reader.h" class MyLogic1 { DataReader& dr; public: MyLogic1( TDataReader& data_reader ) : dr (data_reader) {} // void Work() { // ... моя логи работы; когда мне нужны считанные данные, делаю вот так: printf("Readen data: %dn", dr.Data().my_field); // (!) Так нам не нужно будет использовать никаких глобальных переменных ... } }; files mylogic2.h ... mylogic8.h // Прочие файлы, с реализацией моей логики; они также используют DataReader::Data(), // чтобы получить доступ к считанным данным. file "main.cpp" #include "manager.h" int main(int argc, char* argv[]) { // Инициализируем менеджер Manager manager("my.dat"); // Если инициализация прошла успешно, работаем if (manager.IsInitOk()) { manager.Work(); return 0; } // Ошибка return 1; } Преимуществ реализации без глобальных переменных множество. Главные из них такие: Не будет путаницы имён переменных, когда вы будете разрабатывать сложную программу; Вы сами можете выбрать, где вам хранить ВСЕ данные "скопом" (экземпляр класса Manager): на стеке, на куче или вообще сделать её глобальной; Можно создать множество менеджеров (в зависимости от задачи) и манипулировать ими, как угодно; и многое другое... :) Ну + предлагаю вообще почитать про паттерны проектирования C++, ибо то, что я здесь наваял - это их "велосипедная" смесь. :)

Комментариев нет:

Отправить комментарий