Читаем Язык программирования C++. Пятое издание полностью

int &r4 = 42; // ошибка: нельзя инициализировать простую ссылку из

              //         литерала (раздел 2.3.1)

Те же правила инициализации относятся и к передаче параметров:

int i = 0;

const int ci = i;

string::size_type ctr = 0;

reset(&i);  // вызывает версию функции reset с параметром типа int*

reset(&ci); // ошибка: нельзя инициализировать int* из указателя на

            //         объект const int

reset(i);   // вызывает версию функции reset с параметром типа int&

reset(ci);  // ошибка: нельзя привязать простую ссылку к константному

            //         объекту ci

reset(42);  // ошибка: нельзя привязать простую ссылку к литералу

reset(ctr); // ошибка: типы не совпадают; ctr имеет беззнаковый тип

// ok: первый параметр find_char является ссылкой на константу

find_char("Hello World!", 'o', ctr);

Ссылочную версию функции reset() (см. раздел 6.2.2) можно вызвать только для объектов типа int. Нельзя передать литерал, выражение, результат которого будет иметь тип int, объект, который требует преобразования, или объект типа const int. Точно так же версии функции reset() с указателем можно передать только объект типа int* (см. раздел 6.2.1). С другой стороны, можно передать строковый литерал как первый аргумент функции find_char() (см. раздел 6.2.2). Ссылочный параметр этой функции — ссылка на константу, и можно инициализировать ссылки на константу из литералов.

По возможности используйте ссылки на константы

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

В качестве примера рассмотрим функцию find_char() из раздела 6.2.2. Строковый параметр этой функции правильно сделан ссылкой на константу. Если бы этот параметр был определен как string&:

// ошибка: первый параметр должен быть const string&

string::size_type find_char(string &s, char c,

                            string::size_type &occurs);

то вызвать ее можно было бы только для объекта класса string, так что

find_char("Hello World", 'o', ctr);

привело бы к неудаче во времени компиляции.

Более того, эту версию функции find_char() нельзя использовать из других функций, которые правильно определяют свои параметры как ссылки на константу. Например, мы могли бы использовать функцию find_char() в функции, которая определяет, является ли строка предложением:

bool is_sentence(const string &s) {

 // если в конце s есть точка, то строка s - предложение

 string::size_type ctr = 0;

 return find_char(s, ctr) == s.size() - 1 && ctr == 1;

}

Если бы функция find_char() получала простую ссылку string?, то этот ее вызов привел бы к ошибке при компиляции. Проблема в том, что s — ссылка на const string, но функция find_char() была неправильно определена как получающая простую ссылку.

Было бы заманчиво попытаться исправить эту проблему, изменив тип параметра в функции is_sentence(). Но это только распространит ошибку, так как вызывающая сторона функции is_sentence() сможет передавать только неконстантные строки.

Правильный способ решения этой проблемы — исправить параметр функции find_char(). Если невозможно изменить функцию find_char(), определите локальную копию строки s в функции is_sentence() и передавайте эту строку функции find_char().

Упражнения раздела 6.2.3

Упражнение 6.16. Несмотря на то что следующая функция допустима, она менее полезна, чем могла бы быть. Выявите и исправьте ограничение этой функции:

bool is_empty(string& s) { return s.empty(); }

Перейти на страницу:

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных