Д. Стефенс - C++. Сборник рецептов

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

C++. Сборник рецептов: краткое содержание, описание и аннотация

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

Данная книга написана экспертами по C++ и содержит готовые рецепты решения каждодневных задач для программистов на С++. Один из авторов является создателем библиотеки Boost Iostreams и нескольких других библиотек C++ с открытым исходным кодом. В книге затрагивается множество тем, вот лишь некоторые из них: работа с датой и временем; потоковый ввод/вывод; обработка исключений; работа с классами и объектами; сборка приложений; синтаксический анализ XML-документов; программирование математических задач. Читатель сможет использовать готовые решения, а сэкономленное время и усилия направить на решение конкретных задач.

C++. Сборник рецептов — читать онлайн бесплатно полную книгу (весь текст) целиком

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

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

Интервал:

Закладка:

Сделать

char* buf;

string key_;

}

Обсуждение

Вся работа здесь делается конструктором копирования и закрытой функцией-членом swapInternals. Конструктор копирования инициализирует в списке инициализации элементарные члены и один из неэлементарных членов. Затем он распределяет память для нового буфера и копирует туда данные. Довольно просто, но почему используется такая последовательность действий? Вы могли бы возразить, что всю инициализацию можно сделать в списке инициализации, но такой подход может сопровождаться тонкими ошибками.

Например, вы могли бы следующим образом выделить память под буфер в списке инициализации.

Message(const Message& orig) :

bufSize_(orig bufSize_), initBufSize_(orig initBufSize_),

msgSize_(orig.msgSize_), key_(orig.key_),

buf_(new char[orig.bufSize_]){

copy(orig.buf_, orig.buf_+msgSize_, buf_);

}

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

int bufSize_;

int initBufSize_;

int msgSize_;

char* buf_;

string key_;

В результате buf_будет инициализироваться перед key_. Если при инициализации key_будет выброшено исключение, buf_не будет уничтожен, и у вас образуется участок недоступной памяти. От этого можно защититься путем использования в конструкторе блока try/catch(см. рецепт 9.2), но проще разместить оператор инициализации buf_в теле конструктора, что гарантирует его выполнение после операторов списка инициализации.

Выполнение функции copyне приведет к выбрасыванию исключения, так как она копирует элементарные значения. Но именно это место является тонким с точки зрения безопасности исключений: эта функция может выбросить исключение, если копируются объекты (например, если речь идет о контейнере, который параметризован типом своих элементов, T); в этом случае вам придется перехватывать исключение и освобождать связанную с ним память.

Вы можете поступить по-другому и копировать объект при помощи оператора присваивания, operator=. Поскольку этот оператор и конструктор копирования выполняют аналогичные действия (например, приравнивают члены моего класса к членам аргумента), воспользуйтесь тем, что вы уже сделали, и вы облегчите себе жизнь. Единственная особенность заключается в том, что вы можете сделать более привлекательным ваш программный код, используя закрытую функцию-член для обмена значений между данными-членами и временным объектом. Мне бы хотелось быть изобретателем этого приема, но я обязан отдать должное Гербу Саттеру (Herb Sutter) и Стефану Дьюхарсту (Stephen Dewhurst), в работе которых я впервые познакомился с этим подходом.

Возможно, вам все здесь ясно с первого взгляда, но я дам пояснения на тот случай, если это не так. Рассмотрим первую строку, в которой создается временный объект tmpс помощью конструктора копирования.

Message tmp(rhs);

В данном случае мы просто создали двойника объекта-аргумента. Естественно, теперь tmpэквивалентен rhs. После этого мы обмениваем значения его членов со значениями членов объекта *this.

swapInternals(tmp);

Вскоре я вернусь к функции swapInternals. В данный момент нам важно только то, что члены *thisимеют значения, которые имели члены tmpсекунду назад. Однако объект tmpпредставлял собой копию объекта rhs, поэтому теперь *thisэквивалентен rhs. Но подождите: у нас по-прежнему имеется этот временный объект. Нет проблем, когда вы возвратите *this, tmp будет автоматически уничтожен вместе со старыми значениями переменных-членов при выходе за диапазон его видимости.

return(*this);

Все так. Но обеспечивает ли это безопасность при исключениях? Безопасно конструирование объекта tmp, поскольку наш конструктор является безопасным при исключениях. Большая часть работы выполняется функцией swapInternals, поэтому рассмотрим, что в ней делается, и безопасны ли эти действия при исключениях.

Функция swapInternalsвыполняет обмен значениями между каждым данным-членом текущего объекта и переданного ей объекта. Это делается с помощью функции swap, которая принимает два аргумента a и b , создает временную копию a , присваивает аргумент b аргументу а и затем присваивает временную копию аргументу b . В этом случае такие действия являются безопасными и нейтральными по отношению к исключениям, так как источником исключений здесь могут быть только объекты, над которыми выполняются операции. Здесь не используется динамическая память и поэтому обеспечивается базовая гарантия отсутствия утечки ресурсов.

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

Интервал:

Закладка:

Сделать

Похожие книги на «C++. Сборник рецептов»

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


Отзывы о книге «C++. Сборник рецептов»

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