Общие данные
Иногда необходимо, чтобы к одной переменной можно было обращаться из разных функций. Предположим, в нашей программе используется генератор случайных чисел. Мы хотим инициализировать его один раз, в начале выполнения программы, а затем обращаться к нему из разных частей программы. Рассмотрим несколько возможных реализаций.
Во-первых, определим класс RandomGenerator с двумя методами: Init, для инициализации генератора, и GetNumber — для получения следующего числа.
// // файл RandomGenerator.h // class RandomGenerator { public: RandomGenerator(); ~RandomGenerator(); void Init(unsigned long start); unsigned long GetNumber(); private: unsigned long previousNumber; }; // // файл RandomGenerator.cpp // #include "RandomGenerator.h" #include time.h void RandomGenerator::Init(unsigned long x) { previousNumber = x; } unsigned long RandomGenerator::GetNumber(void) { unsigned long ltime; // получить текущее время в секундах, // прошедших с полуночи 1 января 1970 года time(ltime); ltime = 16; ltime = 16; // взять младшие 16 битов previousNumber = previousNumber * ltime; return previousNumber; }
Первый вариант состоит в создании объекта класса RandomGenerator в функции main и передаче ссылки на него во все функции и методы, где он потребуется.
// файл main.cpp #include "RandomGenerator.h" main() { RandomGenerator rgen; rgen.Init(1000); fun1(rgen); . . . Class1 b(rgen); . . . fun2(rgen); } void fun1(RandomGenerator r) { unsigned long x = r.GetNumber(); . . . } // файл class.cpp #include "RandomGenerator.h" Class1::Class1(RandomGenerator r) { . . . } void fun2(RandomGenerator r) { unsigned long x = r.GetNumber(); . . . }
Поскольку функция main завершает работу программы, все необходимые условия выполнены: генератор случайных чисел создается в самом начале программы, все объекты и функции обращаются к одному и тому же генератору, и генератор уничтожается по завершении программы. Такой стиль программирования допустимо использовать только в том случае, если передавать ссылку на используемый экземпляр объекта требуется нечасто. В противном случае этот способ крайне неудобен. Передавать ссылку на один и тот же объект утомительно, к тому же это загромождает интерфейс классов.