Скотт Майерс - Эффективное использование C++. 55 верных способов улучшить структуру и код ваших программ

Здесь есть возможность читать онлайн «Скотт Майерс - Эффективное использование C++. 55 верных способов улучшить структуру и код ваших программ» — ознакомительный отрывок электронной книги совершенно бесплатно, а после прочтения отрывка купить полную версию. В некоторых случаях можно слушать аудио, скачать через торрент в формате fb2 и присутствует краткое содержание. Город: Москва, Год выпуска: 2006, ISBN: 2006, Издательство: Array Литагент «ДМК», Жанр: Программирование, на русском языке. Описание произведения, (предисловие) а так же отзывы посетителей доступны на портале библиотеки ЛибКат.

Эффективное использование C++. 55 верных способов улучшить структуру и код ваших программ: краткое содержание, описание и аннотация

Предлагаем к чтению аннотацию, описание, краткое содержание или предисловие (зависит от того, что написал сам автор книги «Эффективное использование C++. 55 верных способов улучшить структуру и код ваших программ»). Если вы не нашли необходимую информацию о книге — напишите в комментариях, мы постараемся отыскать её.

Эта книга представляет собой перевод третьего издания американского бестселлера Effective C++ и является руководством по грамотному использованию языка C++. Она поможет сделать ваши программы более понятными, простыми в сопровождении и эффективными. Помимо материала, описывающего общую стратегию проектирования, книга включает в себя главы по программированию с применением шаблонов и по управлению ресурсами, а также множество советов, которые позволят усовершенствовать ваши программы и сделать работу более интересной и творческой. Книга также включает новый материал по принципам обработки исключений, паттернам проектирования и библиотечным средствам.
Издание ориентировано на программистов, знакомых с основами C++ и имеющих навыки его практического применения.

Эффективное использование C++. 55 верных способов улучшить структуру и код ваших программ — читать онлайн ознакомительный отрывок

Ниже представлен текст книги, разбитый по страницам. Система сохранения места последней прочитанной страницы, позволяет с удобством читать онлайн бесплатно книгу «Эффективное использование C++. 55 верных способов улучшить структуру и код ваших программ», без необходимости каждый раз заново искать на чём Вы остановились. Поставьте закладку, и сможете в любой момент перейти на страницу, на которой закончили чтение.

Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

{

delete pb; // прекратить использование текущего

// объекта Bitmap

pb = new Bitmap(*rhs.pb); // начать использование копии объекта

// Bitmap, указанной в правой части

return *this; // см. правило 10

}

Проблема состоит в том, что внутри operator= *this (чему присваивается значение) и rhs (что присваивается) могут оказаться одним и тем же объектом. Если это случится, то delete уничтожит не только Bitmap, принадлежащий текущему объекту, но и Bitmap, принадлежащий объекту в правой части. По завершении работы этой функции Widget, который не должен был бы измениться в процессе присваивания самому себе, содержит указатель на удаленный объект!

Традиционный способ предотвратить эту ошибку состоит в том, что нужно выполнить проверку совпадения в начале operator=:

Widget&

Widget::operator=(const Widget& rhs) // небезопасная реализация operator=

{

if(this == &rhs) return *this; // проверка совпадения: если

// присваивание самому себе, то

// ничего не делать

delete pb;

pb = new Bitmap(*rhs.pb);

return *this;

}

Это решает проблему, но я уже упоминал, что предыдущая версия оператора присваивания была не только опасна в случае присваивания себе, но и небезопасна в смысле исключений, и последняя опасность остается актуальной во второй версии. В частности, если выражение «new Bitmap» вызовет исключение (либо по причине недостатка свободной памяти, либо исключение возбудит конструктор копирования Bitmap), то Widget также будет содержать указатель на несуществующий Bitmap. Такие указатели – источник неприятностей. Их нельзя безопасно удалить, их даже нельзя разыменовывать. А вот потратить массу времени на отладку, выясняя, откуда они взялись, – это можно.

К счастью, существует способ одновременно сделать operator= безопасным в смысле исключений и безопасным по части присваивания самому себе. Поэтому все чаще программисты не занимаются специально присваиванием самому себе, а сосредоточивают усилия на достижении безопасности в смысле исключений. В правиле 29 эта проблема рассмотрена детально, а сейчас достаточно упомянуть, что во многих случаях продуманная последовательность операторов присваивания может обеспечить безопасность в смысле исключений (а заодно безопасность присваивания самому себе) кода. Например, ниже мы просто не удаляем pb до тех пор, пока не скопируем то, на что он указывает:

Widget& Widget::operator=(const Widget& rhs)

{

Bitmap *pOrig = pb; // запомнить исходный pb

pb = new Bitmap(*rhs.pb); // установить указатель pb на копию *pb

delete pOrig; // удалить исходный pb

return *this;

}

Теперь, если «new Bitmap» возбудит исключение, то pb (и объект Widget, которому он принадлежит) останется неизменным. Даже без проверки на совпадение здесь обрабатывается присваивание самому себе, потому что мы сделали копию исходного объекта Bitmap, удалили его, а затем направили указатель на сделанную копию. Возможно, это не самый эффективный способ обработать присваивание самому себе, но он работает.

Если вы печетесь об эффективности, то можете вернуть проверку на совпадение в начале функции. Но прежде спросите себя, как часто может происходить присваивание самому себе, потому что выполнение проверки тоже не обходится даром. Это делает код (исходный и объектный) чуть больше, а ветвление несколько снижает скорость исполнения. Эффективность предварительной выборки команд, кэширования и конвейеризации тоже может пострадать.

Альтернативой ручному упорядочиванию предложений в operator= может быть обеспечение и безопасности в смысле исключений, и безопасности присваивания самому себе за счет применения техники «копирования с обменом» («copy and swap»). Она тесно связана с безопасностью в смысле исключений, поэтому рассматривается в правиле 29. Тем не менее это достаточно распространенный способ написания operator=, и на него стоит взглянуть:

class Widget {

...

void swap(Widget& rhs); // обмен данными *this и rhs

... // см. подробности в правиле 29

};

Widget& Widget:: operator=(const Widget& rhs)

{

Widget temp(rhs); // создать копию данных rhs

swap(tmp); // обменять данные *this с копией

return *this;

}

Здесь мы пользуемся тем, что: (1) оператор присваивания можно объявить как принимающим аргумент по значению и (2) передача объекта по значению означает создание копии этого объекта (см. правило 20):

Widget& Widget::operator=(Widget rhs) // rhs – копия переданного объекта

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

Интервал:

Закладка:

Сделать

Похожие книги на «Эффективное использование C++. 55 верных способов улучшить структуру и код ваших программ»

Представляем Вашему вниманию похожие книги на «Эффективное использование C++. 55 верных способов улучшить структуру и код ваших программ» списком для выбора. Мы отобрали схожую по названию и смыслу литературу в надежде предоставить читателям больше вариантов отыскать новые, интересные, ещё непрочитанные произведения.


Отзывы о книге «Эффективное использование C++. 55 верных способов улучшить структуру и код ваших программ»

Обсуждение, отзывы о книге «Эффективное использование C++. 55 верных способов улучшить структуру и код ваших программ» и просто собственные мнения читателей. Оставьте ваши комментарии, напишите, что Вы думаете о произведении, его смысле или главных героях. Укажите что конкретно понравилось, а что нет, и почему Вы так считаете.

x