Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Прогр_на_ЯВУ (Cpp)_-_Лекции.doc
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
882.69 Кб
Скачать

16.1.1 Общие данные

Иногда необходимо, чтобы к одной переменной можно было обращаться из разных функций. Предположим, в нашей программе используется генератор случайных чисел. Мы хотим инициализировать его один раз, в начале выполнения программы, а затем обращаться к нему из разных частей программы. Рассмотрим несколько возможных реализаций.

Во-первых, определим класс 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 завершает работу программы, все необходимые условия выполнены: генератор случайных чисел создается в самом начале программы, все объекты и функции обращаются к одному и тому же генератору, и генератор уничтожается по завершении программы. Такой стиль программирования допустимо использовать только в том случае, если передавать ссылку на используемый экземпляр объекта требуется нечасто. В противном случае этот способ крайне неудобен. Передавать ссылку на один и тот же объект утомительно, к тому же это загромождает интерфейс классов.

16.1.2 Глобальные переменные

Язык Си++ предоставляет возможность определения глобальной переменной. Если переменная определена вне функции, она создается в самом начале выполнения программы (еще до начала выполнения main). Эта переменная доступна во всех функциях того файла, где она определена. Аналогично прототипу функции, имя глобальной переменной можно объявить в других файлах и тем самым предоставить возможность обращаться к ней и в других файлах:

// файл main.cpp

#include "RandomGenerator.h"

// определение глобальной переменной

RandomGenerator rgen;

main()

{

rgen.Init(1000);

}

void

fun1(void)

{

unsigned long x = rgen.GetNumber();

. . .

}

// файл class.cpp

#include "RandomGenerator.h"

// объявление глобальной переменной,

// внешней по отношению к данному файлу

extern RandomGenerator rgen;

Class1::Class1()

{

. . .

}

void

fun2()

{

unsigned long x = rgen.GetNumber();

. . .

}

Объявление внешней переменной можно поместить в файл-заголовок. Тогда не нужно будет повторять объявление переменной с описателем extern в каждом файле, который ее использует.

Модификацией определения глобальной переменной является добавление описателя static. Для глобальной переменной описатель static означает то, что эта переменная доступна только в одном файле – в том, в котором она определена. (Правда, в данном примере такая модификация недопустима – нам-то как раз нужно, чтобы к глобальной переменной rgen можно было обращаться из разных файлов.)