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


Авторские права

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

Здесь можно скачать бесплатно "Д. Стефенс - C++. Сборник рецептов" в формате fb2, epub, txt, doc, pdf. Жанр: Программирование, издательство КУДИЦ-ПРЕСС, год 2007. Так же Вы можете читать книгу онлайн без регистрации и SMS на сайте LibFox.Ru (ЛибФокс) или прочесть описание и ознакомиться с отзывами.
Д. Стефенс - C++. Сборник рецептов
Рейтинг:
Название:
C++. Сборник рецептов
Автор:
Издательство:
КУДИЦ-ПРЕСС
Год:
2007
ISBN:
5-91136-030-6
Скачать:

99Пожалуйста дождитесь своей очереди, идёт подготовка вашей ссылки для скачивания...

Скачивание начинается... Если скачивание не началось автоматически, пожалуйста нажмите на эту ссылку.

Вы автор?
Жалоба
Все книги на сайте размещаются его пользователями. Приносим свои глубочайшие извинения, если Ваша книга была опубликована без Вашего на то согласия.
Напишите нам, и мы в срочном порядке примем меры.

Как получить книгу?
Оплатили, но не знаете что делать дальше? Инструкция.

Описание книги "C++. Сборник рецептов"

Описание и краткое содержание "C++. Сборник рецептов" читать бесплатно онлайн.



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






 ws(os);     // Передать поток объекту ws

 return(os); // для выполнения реальной работы

}

Это решает проблему, но не в общем виде. Вам не захочется писать класс типа WidthSetter для каждого вашего манипулятора, принимающего аргумент (возможно, вы это и делаете, но были бы не против поступить по-другому), поэтому лучше использовать шаблоны и указатели функций для получения привлекательной, обобщенной инфраструктуры, на базе которой вы можете создавать любое количество манипуляторов. Пример 10.5 содержит класс ManipInfra и версию operator<<, использующую аргументы шаблона для работы с различными типами символов, которые может содержать поток, и с различными типами аргументов, которые могут быть использованы манипулятором потока.

Пример 10.5. Инфраструктура манипуляторов

#include <iostream>

#include <string>


using namespace std;


// ManipInfra - это небольшой промежуточный класс, который помогает

// создавать специальные манипуляторы с аргументами. Вызывайте его

// конструктор с предоставлением указателя функции и значения из основной

// функции манипулятора

// Указатель функции должен ссылаться на вспомогательную функцию, которая

// делает реальную работу. См. примеры ниже

template<typename T, typename C>

class ManipInfra {

public:

 ManipInfra(basic_ostream<C>& (*pFun) (basic_ostream<C>&, T), T val) :

  manipFun_(pFun), val_(val) {}

 void operator()(basic_ostream<C>& os) const {

  manipFun_(os, val_);

 }       // Вызовите функцию, задавая ее указатель и

private: // передавая ей поток и значение

 T val_;

 basic_ostream<С>& (*manipFun_) (basic_ostream<C>&, T);

};


template<typename T, typename C>

basic_ostream<C>& operator<<(basic_ostream<C>& os,

 const ManipInfra<T, C>& manip) {

 manip(os);

 return(os);

}


// Вспомогательная функция, которая вызывается в итоге в классе ManipInfra

ostream& setTheWidth(ostream& os, int n) {

 os.width(n);

 return(os);

}


// Собственно функция манипулятора. Именно она используется в клиентском

// программном коде

ManipInfra<int, char> setWidth(int n) {

 return(ManipInfra<int, char>(setTheWidth, n));

}


// Ещё одна вспомогательная функция, которая принимает аргумент типа char

ostream& setTheFillChar(ostream& os, char с) {

 os.fill(c);

 return(os);

}


ManipInfra<char, char> setFill(char c) {

 return(ManipInfra<char, char>(setTheFillChar, c));

}


int main() {

 cout << setFill('-')

  << setWidth(10) << right << "Proust\n";

}

Если последовательность событий при работе этого класса все же остается неясной, я советую прогнать пример 10.5 через отладчик. Увидев его реальную работу, вы все поймете.

10.4. Создание класса, записываемого в поток

Проблема

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

Решение

Перегрузите operator<< для записи в поток соответствующих данных-членов. В примере 10.6 показано, как это можно сделать.

Пример 10.6. Запись объектов в поток

#include <iostream>

#include <string>


using namespace std;


class Employer {

 friend ostream& operator<<             // Он должен быть другом для

  (ostream& out, const Employer& empr); // получения доступа к неоткрытым

public:                                 // членам

 Employer() {}

 ~Employer() {}

 void setName(const string& name) {name_ = name;}

private:

 string name_;

};


class Employee {

friend ostream& operator<< (ostream& out, const Employee& obj);

public:

 Employee() : empr_(NULL) {}

 ~Employee() {if (empr_) delete empr_;}


 void setFirstName(const string& name) {firstName_ = name;}

 void setLasttName(const string& name) {lastName_ = name;}

 void setEmployer(Employer& empr) {empr_ = &empr;}

 const Employer* getEmployer() const {return(empr_);}

private:

 string firstName_;

 string lastName_;

 Employer* empr_;

};


// Обеспечить передачу в поток объектов

Employer... ostream& operator<<(ostream& out, const Employer& empr) {

 out << empr.name_ << endl; return(out);

}


// Обеспечить передачу в поток объектов Employee...

ostream& operator<<(ostream& out, const Employee& emp) {

 out << emp.firstName_ << endl;

 out << emp.lastName_ << endl;

 if (emp.empr_) out << *emp.empr_ << endl;

  return(out);

}


int main() {

 Employee emp;

 string first = "William";

 string last = "Shatner";

 Employer empr;

 string name = "Enterprise";

 empr.setName(name);

 emp.setFirstName(first);

 emp.setLastName(last);

 emp.setEmployer(empr);

 cout << emp; // Запись в поток

}

Обсуждение

Прежде всего, необходимо объявить оператор operator<< другом (friend) класса, который вы хотите записывать в поток. Вы должны использовать operator<<, а не функцию-член типа writeToStream(ostream& os), потому что этот оператор принято использовать в стандартной библиотеке для записи любых объектов в поток. Вам придется объявить его другом, потому что в большинстве случаев потребуется записывать в поток закрытые члены, а не являющиеся друзьями функции не смогут получить доступ к ним.

После этого определите версию operator<<, которая работает с ostream или wostream (которые определены в <ostream>) и вашим классом, который вы уже объявили с ключевым словом friend. Здесь вы должны решить, какие данные-члены должны записываться в поток. Обычно потребуется записывать в поток все данные, как это я делал в примере 10.6.

out << emp.firstName_ << endl;

out << emp.lastName_ << endl;

В примере 10.6 я записал в поток объект, на который ссылается указатель empr_, вызывая для него оператор operator<<.

if (emp.empr_)

 out << *emp.empr << endl;

Я могу так делать, потому что empr_ указывает на объект класса Employer, а для него, как и для Employee, я определил оператор operator<<.

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

cout << "Here's my object. " << myObj << '\n';

Описанный мною подход достаточно прост, и если вы собираетесь записывать класс с целью его дальнейшего восприятия человеком, он будет хорошо работать, но это только частичное решение проблемы. Если вы записываете объект в поток, это обычно делается по одной из двух причин. Либо этот поток направляется куда-то, где он будет прочитан человеком (cout, окно терминала, файл журнала и т.п.), либо поток записывается на носитель временной или постоянной памяти (stringstream, сетевое соединение, файл и т.д.) и вы планируете восстановить в будущем объект из потока. Если вам требуется воссоздать объект из потока (тема рецепта 10.5), необходимо тщательно продумать взаимосвязи вашего класса.

Сериализация трудно реализуется для любых классов, не считая тривиальных. Если в вашем классе имеются ссылки или указатели на другие классы, что характерно для большинства нетривиальных классов, вам придется учесть потенциальную возможность наличия циклических ссылок, обработать их должным образом при записи в поток объектов и правильно реконструировать ссылки при считывании объектов. Если вам приходится строить что-то «с чистого листа», необходимо учесть эти особенности проектирования, однако если вы можете использовать внешнюю библиотеку, вам следует воспользоваться библиотекой Boost Serialization, которая обеспечивает переносимый фреймворк сериализации объектов.

Смотри также

Рецепт 10.5.

10.5. Создание класса, считываемого из потока

Проблема

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

Решение

Используйте operator>> для чтения данных из потока в ваш класс для заполнения значений данных-членов; это просто является обратной задачей по отношению к тому, что сделано в примере 10.6. Реализация приводится в примере 10.7.


На Facebook В Твиттере В Instagram В Одноклассниках Мы Вконтакте
Подписывайтесь на наши страницы в социальных сетях.
Будьте в курсе последних книжных новинок, комментируйте, обсуждайте. Мы ждём Вас!

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

Книги похожие на "C++. Сборник рецептов" читать онлайн или скачать бесплатно полные версии.


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

Все книги автора Д. Стефенс

Д. Стефенс - все книги автора в одном месте на сайте онлайн библиотеки LibFox.

Уважаемый посетитель, Вы зашли на сайт как незарегистрированный пользователь.
Мы рекомендуем Вам зарегистрироваться либо войти на сайт под своим именем.

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

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

А что Вы думаете о книге? Оставьте Ваш отзыв.