Following the read and write conventions of iostreams, we would insert and extract the date object like this:
date birthday(2,6,1952); std::cout << birthday << '\n';
or
date aDate;
std::cout << '\n' << "Please, enter a date (day month year)"
<< '\n';
std::cin >> aDate;
std::cout << aDate << '\n';
For the next step, we would implement shift operators as inserters and extractors for date objects. Here is an extractor for class date:
template<class charT, class Traits>
std::basic_istream<charT, Traits>& //1
operator>> (std::basic_istream<charT,Traits>& is, //2
date& dat) //3
{
is >> dat.tm_date.tm_mday; //4
is >> dat.tm_date.tm_mon;
is >> dat.tm_date.tm_year;
return is; //5
}
| //1 | The returned value for extractors (and inserters) is a reference to the stream, so that several extractions can be done in one expression. |
| //2 | The first parameter usually is the stream from which the data shall be extracted. |
| //3 | The second parameter is a reference, or alternatively a pointer, to an object of the user-defined type. |
| //4 | In order to allow access to private data of the date class, the extractor must be declared as a friend function in class date. |
| //5 | The return value is the stream from which the data was extracted. |
As the extractor accesses private data members of class date, it must be declared as a friend function to class date. The same holds for the inserter. Here's a more complete version of class date:
class date {
public:
date(int d, int m, int y);
date(tm t);
date();
// more constructors and useful member functions
private:
std::tm tm_date;
template<class charT, Traits>
friend std::basic_istream<charT, Traits>
&operator >>(std::basic_istream<charT, Traits >& is, date& dat);
template<class charT, Traits>
friend std::basic_ostream<charT, Traits>
&operator <<(std::basic_ostream<charT, Traits >& os,
const date& dat);
};
The inserter can be built analogously, as shown below. The only difference is that you would hand over a constant reference to a date object, because the inserter is not supposed to modify the object it prints.
template<class charT, class Traits>
std::basic_ostream<charT, Traits>&
operator << (std::basic_ostream<charT, Traits >& os,
const date& dat)
{
os << dat.tm_date.tm_mon << '-';
os << dat.tm_date.tm_mday << '-';
os << dat.tm_date.tm_year ;
return os;
}