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

Тут можно читать онлайн Д. Стефенс - C++. Сборник рецептов - бесплатно полную версию книги (целиком) без сокращений. Жанр: comp-programming, издательство КУДИЦ-ПРЕСС, год 2007. Здесь Вы можете читать полную версию (весь текст) онлайн без регистрации и SMS на сайте лучшей интернет библиотеки ЛибКинг или прочесть краткое содержание (суть), предисловие и аннотацию. Так же сможете купить и скачать торрент в электронном формате fb2, найти и слушать аудиокнигу на русском языке или узнать сколько частей в серии и всего страниц в публикации. Читателям доступно смотреть обложку, картинки, описание и отзывы (комментарии) о произведении.
  • Название:
    C++. Сборник рецептов
  • Автор:
  • Жанр:
  • Издательство:
    КУДИЦ-ПРЕСС
  • Год:
    2007
  • Город:
    Москва
  • ISBN:
    5-91136-030-6
  • Рейтинг:
    3.9/5. Голосов: 101
  • Избранное:
    Добавить в избранное
  • Отзывы:
  • Ваша оценка:
    • 80
    • 1
    • 2
    • 3
    • 4
    • 5

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

C++. Сборник рецептов - описание и краткое содержание, автор Д. Стефенс, читайте бесплатно онлайн на сайте электронной библиотеки LibKing.Ru

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

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

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

Интервал:

Закладка:

Сделать

картинка 62Члены инициализируются в порядке их указания в объявлении класса, а не в порядке объявления их в списке инициализации.

Используя тот же класс Foo, как и в примере 8.1, рассмотрим переменную-член класса.

class Foo {

public:

Foo() : counter_(0), str_(NULL), cls_(0) {}

Foo(int с, string* p) :

counter_(c), str_(p), cls_(0) {}

private:

int counter_;

string* str_;

SomeClass cls_;

};

В конструкторе по умолчанию Fooинициализировать cls_не требуется, так как будет вызван ее конструктор по умолчанию. Но если требуется создать Fooс аргументами, то следует добавить аргумент в список инициализации, как это сделано выше, а не делать присвоение в теле конструктора. Используя список инициализации, вы избежите дополнительного шага создания cls_(так как при присвоении cls_значения в теле конструктора cls_вначале создается с использованием конструктора по умолчанию, а затем с помощью оператора присвоения выполняется присвоение нового значения), а также получите автоматическую обработку исключений. Если объект создается в списке инициализации и этот объект в процессе его создания выбрасывает исключение, то среда выполнения удаляет все ранее созданные объекты списка и передает исключение в код, вызывавший конструктор. С другой стороны, при присвоении аргумента в теле конструктора такое исключение необходимо обрабатывать с помощью блока try/catch.

Ссылки более сложны: инициализация переменной-ссылки (и const-членов) требует обязательного использования списка инициализации. В соответствии со стандартом ссылка всегда должна ссылаться на одну переменную и никогда не может измениться и ссылаться на другую переменную. Переменная-ссылка никогда не может не ссылаться на какой-либо объект. Следовательно, чтобы присвоить что-то осмысленное переменной-члену, являющейся ссылкой, это должно происходить при инициализации , т.е. в списке инициализации.

Следующая запись в C++ недопустима.

int& x;

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

int а;

int& x = a;

Это все замечательно, но приводит к возникновению проблемы при создании классов. Предположим, вам требуется переменная-член класса, являющаяся ссылкой, как здесь.

class HasARef {

public:

int& ref;

};

Большинство компиляторов примет эту запись, но только до тех пор, пока вы не попытаетесь создать экземпляр этого класса, как здесь.

HasARef me;

В этот момент вы получите ошибку. Вот какую ошибку выдаст gcc.

error: structure 'me' with uninitialized reference members

(ошибка: структура 'me' с неинициализированными членами-ссылками)

Вместо этого следует использовать список инициализации.

class HasARef {

public:

int &ref;

HasARef(int &aref) : ref(aref) {}

};

Затем при создании экземпляра класса требуется указать переменную, на которую будет ссылаться переменная ref, как здесь.

int var;

HasARef me(var);

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

Смотри также

Рецепт 9.2.

8.2. Использование функции для создания объектов (шаблон фабрики)

Проблема

Вместо создания объекта в куче с помощью new вам требуется функция (член или самостоятельная), выполняющая создание объекта, тип которого определяется динамически. Такое поведение достигается с помощью шаблона проектирования Abstract Factory (абстрактная фабрика).

Решение

Здесь есть две возможности. Вы можете:

• создать функцию, которая создает экземпляр объекта в куче и возвращает указатель на этот объект (или обновляет переданный в нее указатель, записывая в него адрес нового объекта);

• создать функцию, которая создает и возвращает временный объект.

Пример 8.2 показывает оба этих способа. Класс Sessionв этом примере может быть любым классом, объекты которого должны не создаваться непосредственно в коде (т.е. с помощью new), а их создание должно управляться каким-либо другим классом. В этом примере управляющий класс — это SessionFactory.

Пример 8.2. Функции, создающие объекты

#include

class Session {};

class SessionFactory {

public:

Session Create();

Session* CreatePtr();

void Create(Session*& p);

// ...

};

// Возвращаем копию объекта в стеке

Session SessionFactory::Create() {

Session s;

return(s);

}

// Возвращаем указатель на объект в куче

Session* SessionFactory::CreatePtr() {

return(new Session());

}

// Обновляем переданный указатель, записывая адрес

// нового объекта

void SessionFactory::Create(Session*& p) {

p = new Session();

}

static SessionFactory f; // Единственный объект фабрики

int main() {

Session* p1;

Session* p2 = new Session();

*p2 = f.Create(); // Просто присваиваем объект, полученный из Create

p1 = f.CreatePtr(); // или полученный указатель на объект в куче

f.Create(p1); // или обновляем указатель новым адресом

}

Обсуждение

Пример 8.2 показывает несколько различных способов написания функции, возвращающей объект. Сделать так вместо обращения к newможет потребоваться, если создаваемый объект берется из пула, связан с оборудованием или удаление объектов должно управляться не вызывающим кодом. Существует множество причин использовать этот подход (и именно поэтому существует шаблон проектирования для него), я привел только некоторые. К счастью, реализация шаблона фабрики в C++ очень проста.

Наиболее часто используют возврат адреса нового объекта в куче или обновление адреса указателя, переданного как аргумент. Их реализация показана в примере 8.2, и она тривиальна и не требует дальнейших пояснений. Однако возврат из функции целого объекта используется реже — возможно, потому, что это требует больших накладных расходов.

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

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

Интервал:

Закладка:

Сделать


Д. Стефенс читать все книги автора по порядку

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




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


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


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

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