Герб Саттер - Стандарты программирования на С++. 101 правило и рекомендация

Тут можно читать онлайн Герб Саттер - Стандарты программирования на С++. 101 правило и рекомендация - бесплатно полную версию книги (целиком) без сокращений. Жанр: comp-programming, издательство Издательский дом Вильямс, год 2005. Здесь Вы можете читать полную версию (весь текст) онлайн без регистрации и SMS на сайте лучшей интернет библиотеки ЛибКинг или прочесть краткое содержание (суть), предисловие и аннотацию. Так же сможете купить и скачать торрент в электронном формате fb2, найти и слушать аудиокнигу на русском языке или узнать сколько частей в серии и всего страниц в публикации. Читателям доступно смотреть обложку, картинки, описание и отзывы (комментарии) о произведении.
  • Название:
    Стандарты программирования на С++. 101 правило и рекомендация
  • Автор:
  • Жанр:
  • Издательство:
    Издательский дом Вильямс
  • Год:
    2005
  • Город:
    Москва
  • ISBN:
    5-8459-0859-0
  • Рейтинг:
    3.3/5. Голосов: 101
  • Избранное:
    Добавить в избранное
  • Отзывы:
  • Ваша оценка:
    • 60
    • 1
    • 2
    • 3
    • 4
    • 5

Герб Саттер - Стандарты программирования на С++. 101 правило и рекомендация краткое содержание

Стандарты программирования на С++. 101 правило и рекомендация - описание и краткое содержание, автор Герб Саттер, читайте бесплатно онлайн на сайте электронной библиотеки LibKing.Ru

Эта книга поможет новичку стать профессионалом, так как в ней представлен сконцентрированный лучший опыт программистов на С++, обобщенный двумя экспертами мирового класса.

Начинающий программист найдет в ней простые и понятные рекомендации для ежедневного использования, подкрепленные примерами их конкретного применения на практике.

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

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

Стандарты программирования на С++. 101 правило и рекомендация - читать онлайн бесплатно полную версию (весь текст целиком)

Стандарты программирования на С++. 101 правило и рекомендация - читать книгу онлайн бесплатно, автор Герб Саттер
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

void Foolish(unsigned int n) {

const unsigned int size = 1;

const_cast(size) = n; // Не делайте так!

char buffer[size]; // Размер массива

// ... // все равно равен 1

}

В С++ имеется одно неявное преобразование const_castиз строкового литерала в char*:

char* weird = "Trick or treat?";

Компилятор молча выполняет преобразование const_castиз const char[16]в char*. Это преобразование позволено для совместимости с API в стиле С, хотя и представляет собой дыру в системе типов С++. Строковые литералы могут размещаться в памяти только для чтения, и попытка изменения такой строки может вызвать нарушение защиты памяти.

Исключения

Преобразование, отменяющее const, может оказаться необходимым для вызова функции API, некорректно указывающей константность (см. рекомендацию 15). Оно также полезно, когда функция, которая должна получать и возвращать ссылку одного и того же типа, имеет как константную, так и неконстантную перегрузки, причем одна из них вызывает другую:

const Object& f(const Object&);

Object& f(Object& obj {

const Object& ref = obj;

return const_cast(f(ref)); // преобразование

} // возвращаемого типа

Ссылки

[Dewhurst03] §32, §40 • [Sutter00] §44

95. Не используйте преобразование типов в стиле С

Резюме

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

Обсуждение

Одна из проблем, связанных с преобразованием типов в стиле С, заключается в том, что оно использует один и тот же синтаксис для выполнения несколько разных вещей, в зависимости от таких мелочей, как, например, какие именно заголовочные файлы включены при помощи директивы #include. Преобразования типов в стиле С++, сохраняя определенную опасность, присущую преобразованиям вообще, имеют четко документированное предназначение, их легко найти, дольше писать (что дает время дважды подумать при их использовании), и не позволяют незаметно выполнить опасное преобразование reinterpret_cast(см. рекомендацию 92).

Рассмотрим следующий код, в котором Derived— производный от базового класса Base:

extern void Fun(Derived*);

void Gun(Base* pb) {

// Будем считать, что функция Gun знает, что pb в

// действительности указывает на объект типа Derived и

// хочет передать его функции Fun

Derived* pd = (Derived*)pb; // Плохо: преобразование

Fun(pd); // в стиле С

}

Если функция Gun имеет доступ к определению Derived(например, при включении заголовочного файла derived.h), то компилятор имеет всю необходимую информацию о размещении объекта, чтобы выполнить все необходимые действия по корректировке указателя при преобразовании от Baseк Derived. Но если автор Gunзабыл включить соответствующий файл определения, и функции Gunвидно только предварительное объявление класса Derived, то компилятор будет полагать, что Baseи Derived— несвязанные типы, и интерпретирует биты указателя Base*как биты указателя Derived*, не делая никаких коррекций, которые могут диктоваться размещением объекта в памяти!

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

extern void Fun(Derived*);

void Gun(Base* pb) {

// Если мы гарантированно знаем, что pb на самом деле

// указывает на объект типа Derived:

// Преобразование в стиле С++

Derived* pd = static_cast(pb);

// В противном случае следует использовать

// = dynamic_cast(pb);

Fun(pd);

}

Теперь, если у компилятора недостаточно статической информации об отношениях между Baseи Derived, он выведет сообщение об ошибке, вместо того чтобы автоматически применить побитовое (и потенциально опасное) преобразование reinterpret_cast (см. рекомендацию 92).

Преобразования в стиле С++ могут защитить корректность вашего кода в процессе эволюции системы. Пусть, например, у вас есть иерархия с корнем в Employee, и вам надо определить уникальный идентификатор IDдля каждого объекта Employee. Вы можете определить ID как указатель на сам объект Employee. Указатели однозначно идентифицируют объекты, на которые указывают, и могут сравниваться на равенство друг другу — что в точности то, что нам и надо. Итак, запишем:

typedef Employee* EmployeeID;

Employee& Fetch(EmployeeID id) {

return *id;

}

Пусть вы кодируете часть системы с данным дизайном. Пусть позже вам требуется сохранять ваши записи в реляционной базе данных. Понятно, что сохранение указателей — не то, что вам требуется. В результате вы изменяете дизайн так, чтобы каждый объект имел уникальный целочисленный идентификатор. Тогда целочисленный идентификатор может храниться в базе данных, а хэш-таблица отображает идентификаторы на объекты Employee. Теперь typedefвыглядит следующим образом:

typedef int EmployeeID;

Employee& Fetch( EmployeeID id ) {

return employeeTable_.lookup(id);

}

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

void TooCoolToUseNewCasts(EmployeeID id) {

Secretary* pSecretary = (Secretary*)id; // Плохо:

// ... // преобразование в стиле С

}

При использовании старой инструкции typedefпреобразование в стиле С выполняет static_cast, при новой будет выполнено reinterpret_castс некоторым целым числом, что даст нам неопределенное поведение программы (см. рекомендацию 92).

Преобразования в стиле С++ проще искать в исходных текстах при помощи автоматического инструментария наподобие grep(но никакое регулярное выражение grepне позволит выловить синтаксис преобразования типов в стиле С). Поскольку преобразования очень опасны (в особенности static_castдля указателей и reinterpret_cast; см. рекомендацию 92), использование автоматизированного инструментария для их отслеживания — неплохая идея.

Ссылки

[Dewhurst03] §40 • [Meyers96] §2 • [Stroustrup00] §15.4.5 • [Sutter00] §44

96. Не применяйте memcpyили memcmpк не-POD типам

Резюме

Не работайте рентгеновским аппаратом (см. рекомендацию 91). Не используйте memcpyи memcmpдля копирования или сравнения чего-либо структурированного более, чем обычная память.

Читать дальше
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать


Герб Саттер читать все книги автора по порядку

Герб Саттер - все книги автора в одном месте читать по порядку полные версии на сайте онлайн библиотеки LibKing.




Стандарты программирования на С++. 101 правило и рекомендация отзывы


Отзывы читателей о книге Стандарты программирования на С++. 101 правило и рекомендация, автор: Герб Саттер. Читайте комментарии и мнения людей о произведении.


Понравилась книга? Поделитесь впечатлениями - оставьте Ваш отзыв или расскажите друзьям

Напишите свой комментарий
x