Д. Стефенс - 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++. Сборник рецептов - читать книгу онлайн бесплатно, автор Д. Стефенс
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

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

#include

#include

using namespace std;

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

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

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

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

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

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

template

class ManipInfra {

public:

ManipInfra(basic_ostream& (*pFun) (basic_ostream&, T), T val) :

manipFun_(pFun), val_(val) {}

void operator()(basic_ostream& os) const {

manipFun_(os, val_);

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

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

T val_;

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

};

template

basic_ostream& operator<<(basic_ostream& os,

const ManipInfra& manip) {

manip(os);

return(os);

}

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

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

os.width(n);

return(os);

}

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

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

ManipInfra setWidth(int n) {

return(ManipInfra(setTheWidth, n));

}

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

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

os.fill(c);

return(os);

}

ManipInfra setFill(char c) {

return(ManipInfra(setTheFillChar, c));

}

int main() {

cout << setFill('-')

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

}

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

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

Проблема

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

Решение

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

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

#include

#include

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(которые определены в ) и вашим классом, который вы уже объявили с ключевым словом 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.

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

Интервал:

Закладка:

Сделать


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

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




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


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


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

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