Вообще ИМХО, раз уж задачка решается на 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 <string>
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++, ибо то, что я здесь наваял - это их "велосипедная" смесь. :)