- Любовные романы
- Фантастика и фэнтези
- Ненаучная фантастика
- Ироническое фэнтези
- Научная Фантастика
- Фэнтези
- Ужасы и Мистика
- Боевая фантастика
- Альтернативная история
- Космическая фантастика
- Попаданцы
- Юмористическая фантастика
- Героическая фантастика
- Детективная фантастика
- Социально-психологическая
- Боевое фэнтези
- Русское фэнтези
- Киберпанк
- Романтическая фантастика
- Городская фантастика
- Технофэнтези
- Мистика
- Разная фантастика
- Иностранное фэнтези
- Историческое фэнтези
- LitRPG
- Эпическая фантастика
- Зарубежная фантастика
- Городское фентези
- Космоопера
- Разное фэнтези
- Книги магов
- Любовное фэнтези
- Постапокалипсис
- Бизнес
- Историческая фантастика
- Социально-философская фантастика
- Сказочная фантастика
- Стимпанк
- Романтическое фэнтези
- Ироническая фантастика
- Детективы и Триллеры
- Проза
- Юмор
- Феерия
- Новелла
- Русская классическая проза
- Современная проза
- Повести
- Контркультура
- Русская современная проза
- Историческая проза
- Проза
- Классическая проза
- Советская классическая проза
- О войне
- Зарубежная современная проза
- Рассказы
- Зарубежная классика
- Очерки
- Антисоветская литература
- Магический реализм
- Разное
- Сентиментальная проза
- Афоризмы
- Эссе
- Эпистолярная проза
- Семейный роман/Семейная сага
- Поэзия, Драматургия
- Приключения
- Детская литература
- Загадки
- Книга-игра
- Детская проза
- Детские приключения
- Сказка
- Прочая детская литература
- Детская фантастика
- Детские стихи
- Детская образовательная литература
- Детские остросюжетные
- Учебная литература
- Зарубежные детские книги
- Детский фольклор
- Буквари
- Книги для подростков
- Школьные учебники
- Внеклассное чтение
- Книги для дошкольников
- Детская познавательная и развивающая литература
- Детские детективы
- Домоводство, Дом и семья
- Юмор
- Документальные книги
- Бизнес
- Работа с клиентами
- Тайм-менеджмент
- Кадровый менеджмент
- Экономика
- Менеджмент и кадры
- Управление, подбор персонала
- О бизнесе популярно
- Интернет-бизнес
- Личные финансы
- Делопроизводство, офис
- Маркетинг, PR, реклама
- Поиск работы
- Бизнес
- Банковское дело
- Малый бизнес
- Ценные бумаги и инвестиции
- Краткое содержание
- Бухучет и аудит
- Ораторское искусство / риторика
- Корпоративная культура, бизнес
- Финансы
- Государственное и муниципальное управление
- Менеджмент
- Зарубежная деловая литература
- Продажи
- Переговоры
- Личная эффективность
- Торговля
- Научные и научно-популярные книги
- Биофизика
- География
- Экология
- Биохимия
- Рефераты
- Культурология
- Техническая литература
- История
- Психология
- Медицина
- Прочая научная литература
- Юриспруденция
- Биология
- Политика
- Литературоведение
- Религиоведение
- Научпоп
- Психология, личное
- Математика
- Психотерапия
- Социология
- Воспитание детей, педагогика
- Языкознание
- Беременность, ожидание детей
- Транспорт, военная техника
- Детская психология
- Науки: разное
- Педагогика
- Зарубежная психология
- Иностранные языки
- Филология
- Радиотехника
- Деловая литература
- Физика
- Альтернативная медицина
- Химия
- Государство и право
- Обществознание
- Образовательная литература
- Учебники
- Зоология
- Архитектура
- Науки о космосе
- Ботаника
- Астрология
- Ветеринария
- История Европы
- География
- Зарубежная публицистика
- О животных
- Шпаргалки
- Разная литература
- Зарубежная литература о культуре и искусстве
- Пословицы, поговорки
- Боевые искусства
- Прочее
- Периодические издания
- Фанфик
- Военное
- Цитаты из афоризмов
- Гиды, путеводители
- Литература 19 века
- Зарубежная образовательная литература
- Военная история
- Кино
- Современная литература
- Военная техника, оружие
- Культура и искусство
- Музыка, музыканты
- Газеты и журналы
- Современная зарубежная литература
- Визуальные искусства
- Отраслевые издания
- Шахматы
- Недвижимость
- Великолепные истории
- Музыка, танцы
- Авто и ПДД
- Изобразительное искусство, фотография
- Истории из жизни
- Готические новеллы
- Начинающие авторы
- Спецслужбы
- Подростковая литература
- Зарубежная прикладная литература
- Религия и духовность
- Старинная литература
- Справочная литература
- Компьютеры и Интернет
- Блог
Язык программирования C++. Пятое издание - Стенли Липпман
Шрифт:
Интервал:
Закладка:
Отладку можно "выключить", предоставив директиву #define, определяющую переменную NDEBUG. В качестве альтернативы большинство компиляторов предоставляет параметр командной строки, позволяющий определять переменные препроцессора:
$ CC -D NDEBUG main.С # use /D with the Microsoft compiler
Результат будет тот же, что и при наличии строки #define NDEBUG в начале файла main.С.
Когда переменная NDEBUG определена, программа во время выполнения избегает дополнительных затрат на проверку различных условий. Самих проверок во время выполнения, конечно, тоже не будет. Поэтому макрос assert следует использовать только для проверки того, что действительно недопустимо. Это может быть полезно при отладке программы, но не должно использоваться для замены логических проверок времени выполнения или проверки ошибок, которые должна осуществлять программа.
В дополнение к макросу assert можно написать собственный отладочный код, выполняющийся в зависимости от переменной NDEBUG. Если переменная NDEBUG не определена, код между директивами #ifndef и #endif выполняется, а в противном случае игнорируется:
void print(const int ia[], size_t size) {
#ifndef NDEBUG
// __func__ - локальная статическая переменная, определенная
// компилятором. Она содержит имя функции
cerr << __func__ << ": array size is " << size << endl;
#endif
// ...
Здесь переменная __func__ используется для вывода имени отлаживаемой функции. Компилятор определяет переменную __func__ в каждой функции. Это локальный статический массив типа const char, содержащий имя функции.
Кроме переменной __func__, определяемой компилятором С++, препроцессор определяет четыре других имени, которые также могут пригодиться при отладке:
__FILE__ строковый литерал, содержащий имя файла.
__LINE__ целочисленный литерал, содержащий номер текущий строки.
__TIME__ строковый литерал, содержащий файл и время компиляции.
__DATE__ строковый литерал, содержащий файл и дату компиляции.
Эти константы можно использовать для отображения дополнительной информации в сообщениях об ошибках:
if (word.size() < threshold)
cerr << "Error: " << __FILE__
<< " : in function " << __func__
<< " at line " << __LINE__ << endl
<< " Compiled on " << __DATE__
<< " at " << __TIME__ << endl
<< " Word read was "" << word << "": Length too short" << endl;
Если передать этой программе строку, которая короче threshold, то будет создано следующее сообщение об ошибке:
Error: wdebug.cc : in function main at line 27
Compiled on Jul 11 2012 at 20:50:03
Word read was "foo": Length too short
Упражнения раздела 6.5.3Упражнение 6.47. Пересмотрите программу, написанную в упражнении раздела 6.3.2, где использовалась рекурсия для отображения содержимого вектора так, чтобы условно отображать информацию о ее выполнении. Например, отобразите размер вектора при каждом вызове. Откомпилируйте и запустите программу с включенной отладкой и с выключенной.
Упражнение 6.48. Объясните, что делает этот цикл и стоит ли использовать в нем макрос assert:
string s;
while (cin >> s && s != sought) { } // пустое тело
assert(cin);
6.6. Подбор функции
Во многих (если не во всех) случаях довольно просто выяснить, какая из перегруженных версий функции будет использована при данном вызове. Но это не так просто, когда у перегруженных функций одинаковое количество параметров и когда один или несколько параметров имеют типы, связанные преобразованиями. Для примера рассмотрим следующий набор перегруженных функций и их вызов:
void f() ;
void f(int) ;
void f(int, int);
void f(double, double = 3.14);
f(5.6); // вызов void f(double, double)
Выявление кандидатов и подходящих функцийНа первом этапе подбора перегруженной функции выявляют набор версий, подходящих для рассматриваемого вызова. Такие функции называются функциями-кандидатами (candidate function). Функция-кандидат имеет имя, указанное при вызове, и видима в точке вызова. В данном примере кандидатами являются все четыре функции по имени f.
На втором этапе выбора функции из набора кандидатов выявляются те, которые могут быть вызваны с аргументами данного вызова. Выбранные функции называют подходящими (viable function). Чтобы считаться подходящей, функция должна иметь столько же параметров, сколько аргументов передано при вызове, и тип каждого аргумента должен совпадать или допускать преобразование в тип соответствующего параметра.
При вызове f(5.6) две функции-кандидата можно исключить сразу из-за несоответствия количеству аргументов. Речь идет о версии без параметров и версии с двумя параметрами типа int. В данном случае вызов имеет только один аргумент, а эти функции не имеют их вообще или имеют два параметра соответственно.
Функция, получающая один аргумент типа int, и функция, получающая два аргумента типа double, могли бы быть подходящими. Любая из них может быть вызвана с одним аргументом. Функция, получающая два аргумента типа double, имеет аргумент по умолчанию, а значит, может быть вызвана с одним аргументом.
Когда у функции есть аргументы по умолчанию (см. раздел 6.5.1), при вызове может быть передано меньше аргументов, чем она фактически имеет.
После проверки количества аргументов, позволяющей выявить функции, подходящие потенциально, проверяется соответствие типов параметров функций типам аргументов, переданных при вызове. Как и при любом обращении, тип аргумента может либо совпадать, либо допускать преобразование в тип параметра. В данном случае подходят обе оставшиеся функции.
• Функция f(int) является подходящей потому, что аргумент типа double может быть неявно преобразован в параметр типа int.
• Функция f(double, double) также является подходящей потому, что для второго параметра задано значение по умолчанию, а первый параметр имеет тип double, который точно соответствует типу аргумента.
Если никаких подходящих функций не обнаружено, компилятор выдает сообщение об ошибке.
Поиск наилучшего соответствия, если он естьНа третьем этапе подбора перегруженной функции выясняется, какая из допустимых функций наилучшим образом соответствует вызову. Этот процесс анализирует каждый аргумент вызова и выбирает подходящую функцию (или функции), для которой соответствие параметра аргументу является наилучшим. Подробно критерии наилучшего соответствия рассматриваются в следующем разделе, а пока достаточно знать, что чем ближе типы аргумента и параметра друг к другу, тем лучше соответствие.
В данном случае существует только один (явный) аргумент, который имеет тип double. При вызове версии f(int) аргумент преобразуется из типа double в тип int. Вторая подходящая функция, f(double, double), точно соответствует типу этого аргумента. Поскольку точное соответствие лучше соответствия требующего преобразования, компилятор предпочитает версию с двумя параметрами типа double. Для второго, недостающего аргумента компилятор добавит аргумент по умолчанию.
Подбор перегруженной версии с несколькими параметрамиЕсли у функции два или несколько аргументов, подбор подходящей версии усложняется. Предположим, что функции имеют то же имя f, но анализируется следующий вызов:
f(42, 2.56);
Набор подходящих функций выявляется, как прежде. Компилятор выбирает те версии функции, которые имеют необходимое количество параметров, типы которых соответствуют типам аргументов. В данном случае в набор подходящих вошли функции f(int, int) и f(double, double). Затем компилятор перебирает аргументы один за одним и определяет, какая из версий функций имеет наилучшее соответствие. Наилучше соответствующая функция та, для которой единственной выполняются следующие условия.
• Соответствие по каждому аргументу не хуже, чем у остальных подходящих функций.
• По крайней мере у одного аргумента соответствие лучше, чем у остальных подходящих функций.
Если после просмотра всех аргументов не было найдено ни одной функции, которая считалась бы наилучше соответствующей, компилятор сообщает об ошибке неоднозначности вызова.
В рассматриваемом примере вызова анализ лишь первого аргумента для версии f(int, int) функции f() обнаруживает точное соответствие. При анализе второй версии функции f() оказывается, что аргумент 42 типа int следует преобразовать в значение типа double. Соответствие в результате встроенного преобразования хуже, чем точное. Таким образом, рассматривая только этот параметр, лучше соответствует та версия функции f(), которая обладает двумя параметрами типа int, а не двумя параметрами типа double.

