Программирование >>  Синтаксис инициирования исключений 

1 [ 2 ] 3 4 5 ... 82




Синтаксис С++


За годы преподавания C++ я узнал, что подавляющее большинство программистов C++ (включая самых опытных) редко пользуется некоторыми возможностями языка. Конечно, дело это сугубо индивидуальное, но при всей сложности и глубине C++ небольшой обзор не повредит никому. В этой и двух следующих главах я постараюсь выровнять уровень подготовки читателей перед тем, как переходить к действительно интересным темам. Эта глава не заменит Annotated Reference Manual или другое справочное руководство - вы не найдете в ней полной спецификации языка. Я лишь рассмотрю некоторые языковые средства, которые часто понимаются неверно или не понимаются вовсе. Придержите шляпу и приготовьтесь к стремительному облету синтаксиса C++!

Переменные и константы

Болтовню о том, что такое переменные и для чего они нужны, пропускаем. Нашего внимания заслуживают две темы: константность и сравнение динамических объектов со стековыми.

const

Ключевое слово const, которое в разных контекстах принимает разные значения, одно из самых информативных в C++. Да, между этими значениями есть кое-что общее, но вам все равно придется запомнить все конкретные случаи.

Константные переменные

Если переменная объявлена с ключевым словом const, значит, она не должна меняться. После определения константной переменной вы уже не сможете изменить ее значение или передать ее в качестве аргумента функции, которая не гарантирует ее неизменности. Рассмотрим простой пример с константной целой переменной.

const int j = 17; Целая константа

j = 29; Нельзя, значение не должно меняться

const int i; Нельзя, отсутствует начальное значение

Третья строка неверна, поскольку в ней компилятору предлагается определить случайную переменную, которую никогда не удастся изменить, - этакий странный генератор случайных целых констант. Вообще говоря, вы сообщаете компилятору, какой конструктор он должен использовать в конкретном случае. Если бы переменная i относилась к нетривиальному классу, то при объявлении константного экземпляра пришлось бы явно указать конструктор и его аргументы. int - вырожденный случай, поскольку на самом деле const int j=17; - то же, что и int j(17).

Но вот компилятор узнал, что нечто должно быть константным. Он просыпается и начинает искать ошибки - не только фактические, но и потенциальные. Компилятор не разрешит использовать ваше константное нечто в любом неконстантном контексте, даже если шестилетний ребенок разберется в программе и докажет, что в ней нет ни одной ошибки.

const i = 17;

int& j = 1; Нельзя, потому что позднее j может измениться



Не важно, будете ли вы изменять величину, на которую ссылается j. Компилятор предполагает, что вам захочется это сделать, и на всякий случай устраняет искушение. Иначе говоря, константность - свойство переменной, а не данных, поэтому неконстантная переменная не может ссылаться на константную величину.

const и #define

Две следующие строки не эквивалентны: const int i = 17; #define i 17;

В первой строке определяется переменная, занимающая некоторую область памяти, а во второй - макрос. Обычно отличия несущественны, если не считать одного-двух лишних тактов, затраченных на каждое обращение к константной переменной. Однако если переменная является глобальной и принадлежит нетривиальному классу со своим конструктором, ситуация резко меняется. Дополнительные сведения приведены в разделе Инициализация глобальных объектов этой главы.

Константы в перечислениях

Перечисления (епит) не очень широко использовались в языке С по одной простой причине: символические имена констант имеют глобальную область действия и быстро захламляют пространство имен. В C++ эта проблема исчезла, поскольку область действия символических имен ограничивается классом или структурой.

class Foo { public:

enum Status { kOpen = 1, kClosed };

Где-то в программе Foo::Status s = Foo::kOpen;

Обратите внимание - область действия должна быть явно указана как в имени типа, так и в символическом имени. Следовательно, символические имена kOpen и kClosed можно использовать в программе и для других целей. Компилятор рассматривает символические имена перечислений как макросы, а не как константные переменные. Это обстоятельство может оказаться важным при инициализации глобальных переменных (см, далее в этой главе).

Указатель на константу

С указателями дело обстоит несколько сложнее, поскольку приходится учитывать два значения: адрес и содержимое памяти по этому адресу. В следующем примере р - это указатель на константу; находящийся в указателе адрес может измениться, но содержимое памяти по этому адресу - нет.

const int* p; int i = 17;

p = &i; Можно

*p = 29; Нельзя

Сказанное также относится к структурам и объектам. class foo { public:

int x;

const foo* f = new foo;

f->x = 17; Нельзя, присвоение членам класса не допускается



1 [ 2 ] 3 4 5 ... 82

© 2006 - 2024 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки.
Яндекс.Метрика