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

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

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

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

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

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

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

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

Интервал:

Закладка:

Сделать

А теперь давайте рассмотрим возможность конструирования объекта в «куче» с возвратом ссылки на него. Объекты в «куче» создаются посредством new. Вот как мог бы выглядеть operator* в этом случае:

const Rational& operator*(const Rational& lhs, // предупреждение!

const Rational& rhs) // Опять плохой код!

{

Rational *result = new Rational(lhs.n * rhs.h, lhs.d * rhs.d);

return *result;

}

Да, вам все же придется расплачиваться за вызов конструктора, поскольку память, выделяемая new, инициализируется вызовом соответствующего конструктора, но теперь возникает новая проблема: кто выполнит delete для объекта, созданного вами с использованием new?

Даже если вызывающая программа написана аккуратно и добросовестно, не вполне понятно, как она предотвратит утечку в следующем вполне естественном сценарии:

Rational w, x, y, z;

w = x * y * z; // то же, что operator*(operator*(x, y), z)

Здесь выполняется два вызова operator* в одном предложении, поэтому получаются два вызова new, которым должны соответствовать два delete. Но у пользователя operator* нет возможности это сделать, так как он не может получить указатели, скрытые за ссылками, которые возвращает функция operator*. Это гарантированная утечка ресурсов.

Но, возможно, вы заметили, что оба подхода (на основе стека и на основе кучи) страдают от необходимости вызова конструкторов для каждого возвращаемого значения operator*. Вспомните, что исходно мы ставили себе целью вообще не вызывать конструкторы. Быть может, вы думаете, что знаете, как избежать всего, всех вызовов конструктора, кроме одного. Не исключено, что вы придумали следующую реализацию функции operator*, которая возвращает ссылку на статический объект Rational, определенный внутри функции:

const Rational& operator*(const Rational& lhs, // предупреждение!

const Rational& rhs) // Код еще хуже!

{

static Rational result; // статический объект,

// на который возвращается ссылка

result = ...; // умножить lhs на rhs и поместить

// произведение в result

return result;

}

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

bool operator==(const Rational& lhs, // оператор == для Rational

const Rational& rhs);

Rational a, b, c, d;

...

if ((a*b) == (c*d)) {

действия, необходимые в случае, если два произведения равны;

} else {

действия, необходимые в противном случае;

}

Догадываетесь, что не так? Выражение ((a*b) == (c*d)) будет всегда равно true независимо от значений a, b, c и d!

Легче всего найти объяснение такому неприятному поведению, переписать проверку на равенство в эквивалентной функциональной форме:

if(operator==(operator*(a, b), operator*(c, d)))

Заметьте, что когда вызывается operator==, уже присутствуют два активных вызова operator*, каждый из которых будет возвращать ссылку на статический объект Rational внутри operator*. Таким образом, operator== будет сравнивать статический объект Rational, определенный в функции operator*, со значением статического объект Rational внутри той же функции. Было бы удивительно, если бы они не оказались равны всегда.

Этого должно быть достаточно, чтобы убедить вас, что возвращение ссылки из функции, подобной operator*, – пустая трата времени, но я не настолько наивен, чтобы полагаться на везение. Кое-кто в настоящий момент думает: «Хорошо, если недостаточно одного статического объекта, то, может быть, для этого подойдет статический массив…»

Я не снизойду до того, чтобы посвятить такой программе отдельный пример, но вкратце могу пояснить, почему даже возникновение такой идеи должно повергать вас в стыд. Во-первых, вы должны выбрать n – размер массива. Если n слишком мало, у вас может закончиться место для хранения, и вы ничего не выиграете по сравнению с вышеописанной программой. Если же n чересчур велико, вы уменьшаете производительность вашей программы, поскольку каждый объект в массиве конструируется при первом вызове функции. Это будет стоить вам n вызовов конструкторов и n вызовов деструкторов, даже если данная функция вызывается всего один раз. Если процесс повышения производительности программного обеспечения называется оптимизацией, тогда самое верное название происходящему – «пессимизация». И наконец, подумайте о том, как заносить необходимые вам значения в массив объектов и во что это обойдется. Наиболее прямой способ передачи объектов – операция присваивания, но с чем она связана? В общем случае это вызов деструктора (для уничтожения старого значения) плюс вызов конструктора (для копирования нового значения). А ваша цель – избежать вызовов конструктора и деструктора! Так что затея весьма неудачна (нет-нет: применение векторов вместо массивов не улучшит ситуацию).

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

Интервал:

Закладка:

Сделать

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

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


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

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

x