int main() {
cout << setFill('-')
<< setWidth(10) << right << 'Proust
';
}
Если последовательность событий при работе этого класса все же остается неясной, я советую прогнать пример 10.5 через отладчик. Увидев его реальную работу, вы все поймете.
10.4. Создание класса, записываемого в поток
Требуется записать класс в поток для последующего его чтения человеком или с целью его хранения в постоянной памяти, т.е. для его сериализации.
Перегрузите operator<<
для записи в поток соответствующих данных-членов. В примере 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
, я определил оператор