const int bufSize = 512; // размер буфера ввода
Это определит переменную bufSize
как константу. Любая попытка присвоить ей значение будет ошибкой:
bufSize = 512; // ошибка: попытка записи в константный объект
Поскольку нельзя изменить значение константного объекта после создания, его следует инициализировать. Как обычно, инициализатор может быть выражением любой сложности:
const int i = get_size(); // ok: инициализация во время выполнения
const int j = 42; // ok: инициализация во время компиляции
const int k; // ошибка: k - неинициализированная константа
Как уже упоминалось не раз, тип объекта определяет операции, которые можно с ним выполнять. Константный тип можно использовать для большинства, но не для всех операций, как и его неконстантный аналог. Ограничение одно — можно использовать только те операции, которые неспособны изменить объект. Например, тип const int
можно использовать в арифметических выражениях точно так же, как обычный неконстантный тип int
. Тип const int
преобразуется в тип bool
тем же способом, что и обычный тип int
, и т.д.
К операциям, не изменяющим значение объекта, относится инициализация. При использовании объекта для инициализации другого объекта не имеет значения, один или оба из них являются константами.
int i = 42;
const int ci = i; // ok: значение i копируется в ci
int j = ci; // ok: значение ci копируется в j
Хотя переменная ci
имеет тип const int
, ее значение имеет тип int
. Константность переменной ci
имеет значение только для операций, которые могли бы изменить ее значение. При копировании переменной ci
для инициализации переменной j
ее константность не имеет значения. Копирование объекта не изменяет его. Как только копия сделана, у нового объекта нет никакой дальнейшей связи с исходным объектом.
Когда константный объект инициализируется константой во время компиляции, такой как bufSize
в определении ниже, компилятор обычно заменяет используемую переменную ее значением во время компиляции.
const int bufSize = 512; // размер буфера ввода
Таким образом, компилятор создаст исполняемый код, использующий значение 512
в тех местах, где исходный код использует переменную bufSize
.
Чтобы заменить переменную значением, компилятор должен видеть ее инициализатор. При разделении программы на несколько файлов, в каждом из которых используется константа, необходим доступ к ее инициализатору. Для этого переменная должна быть определена в каждом файле, в котором используется ее значение (см. раздел 2.2.2). Для обеспечения такого поведения, но все же без повторных определений той же переменной, константные переменные определяются как локальные для файла. Определение константы с тем же именем в нескольких файлах подобно написанию определения для отдельных переменных в каждом файле.
Иногда константу необходимо совместно использовать в нескольких файлах, однако ее инициализатор не является константным выражением. Мы не хотим, чтобы компилятор создал отдельную переменную в каждом файле, константный объект должен вести себя как другие (не константные) переменные. В таком случае определить константу следует в одном файле, и объявить ее в других файлах, где она тоже используется.
Для определения единого экземпляра константной переменной используется ключевое слово extern
как в ее определении, так и в ее объявлениях.
// Файл file_1.cc. Определение и инициализация константы, которая
// доступна для других файлов
extern const int bufSize = fcn();
// Файл file_1.h
extern const int bufSize; // та же bufSize, определенная в file_1.cc