Создание собственных функций внесения и извлечения
Мы уже говорили, что операторы >> и << можно перегружать, причем, вы сами можете создать свои операторы извлечения и внесения для создаваемых вами типов.
В общем виде, операция внесения имеет следующую форму
ostream& operator << (ostream& stream, имя_класса& obj)
{
stream << ... // вывод элементов объекта obj
// в поток stream, используя готовые функции внесения
return stream;
}
Аналогичным образом может быть определена функция извлечения
istream& operator << (istream& stream, имя_класса& obj)
{
stream >> ... // ввод элементов объекта obj
// из потока stream, используя готовые функции внесения
return stream;
}
Функции внесения и извлечения возвращают ссылку на соответствующие объекты, являющиеся, соответственно, потоками вывода или ввода. Первые аргументы тоже должны быть ссылкой на поток. Второй параметр - ссылка на объект, выводящий или получающий информацию.
Эти функции не могут быть методами класса, для работы с которым они создаются. Если бы это было так, то левым аргументом, при вызове операции << (или >>), должен стоять объект, генерирующий вызов этой функции.
cout << "Моя строка"; а сout.operator << ("Моя строка"); // ошибка
Получается, что функция внесения, определяемая для объектов вашего класса, должна быть методом объекта cout.
Однако при этом можно столкнуться с серьезным ограничением, в случае, когда необходимо вывести (или ввести) значения защищенных членов класса. По этой причине, как правило, функции внесения и извлечения объявляют дружественными к создаваемому вами классу.
class _3d
{
double x, y, z;
public:
_3d ();
_3d (double initX, double initY, double initZ);
double mod () {return sqrt (x*x + y*y +z*z);}
double projection (_3d r) {return (x*r.x + y*r.y + z*r.z) / mod();}
_3d& operator + (_3d& b);
_3d& operator = (_3d& b);
friend ostream& operator << (ostream& stream, _3d& obj);
friend istream& operator >> (istream& stream, _3d& obj);
};
ostream& operator << (ostream& stream, _3d& obj)
{
stream << "x=" << obj.x<< "y=" << obj.y << "z=" << obj.z;
return stream;
}
istream& operator << (istream& stream, _3d& obj)
{
stream >> obj.x >> obj.y >> obj.z;
return stream;
}
main()
{
_3d vecA;
cin >> vecA;
cout << "My vector: " << vecA << "\n";
}
Хотя в функции внесения (или извлечения) может выполняться любая операция, лучше ограничить ее работу только выводом (или вводом) информации.