Consider following program.
#include <iostream>
using std::ostream;
using std::cout;
using std::istream;
using std::cin;
class three_d {
int i,j,k;
public:
three_d(int a,int b,int c) : i(a),j(b),k(c)
{ }
//friend ostream& operator << (ostream&,const three_d&);
//friend istream& operator >> (istream&,three_d&);
};
/*ostream& operator << (ostream& o,const three_d& t) {
o<<t.i<<", ";
o<<t.j<<", ";
o<<t.k<<"\n";
return o;
}
istream& operator >> (istream& stream,three_d &t) {
cout<<"Enter x,y,z values";
stream>>t.i>>t.j>>t.k;
return stream;
}*/
int main() {
three_d a(1,2,3),b(4,5,6),c(7,8,9);
cout<<a<<b<<c;
cin>>a;
cout<<a;
}
I've deliberately commented out the overloaded >> & << operator function definitions and compiler gives following error messages
*[Error] no match for 'operator<<' (operand types are 'std::ostream {aka std::basic_ostream<char>}' and 'three_d')
[Error] no match for 'operator>>' (operand types are 'std::istream {aka std::basic_istream<char>}' and 'three_d')*
By default even for empty class C++ compiler automatically provides following if programmer doesn't provide them.
1) Constructor
2) Destructor
3) Copy constructor
4) =(assigment) operator
Then why >> & << operators has to be explicitly overloaded by programmer to work with user defined types(class)? Wouldn't it be very nice if compiler by default provides overloaded >> & << operator functions for user defined types also? Doesn't that reduce the code required to write & reduces burden for the programmer?
Then why >> & << operators has to be explicitly overloaded by programmer to work with user defined types(class)?
None of what you listed as defaults provides serialization or deserialization, which are two very complicated problems to solve generally.
All four things you listed are allowed to reorder their operations semantically, however serialization/deserialization cannot.
Additionally what format should the serialized data be in? Binary or text? What separator should be between data fields? Should the data fields be named or simply ordered?
Finally none of the original four can fail, however istream
could for a multitude of reasons. What do you do when it fails? Do you return a partially initialized and partially defaulted class or do you throw an exception?
It isn't that this series of questions is unanswerable, it is that the answer depends on what the rest of your code is doing, so a general answer is impossible. Lots of places want to be able to save their data for latter so a compact binary representation is good. Other places want to be able to show the user a data structure easily, which requires a text representation.
Additionally by far the biggest factor against the idea is the inherent cost of adding features. This is answer on that topic (there have been some more comprehensive blog posts about the topic but I don't have a link handy sorry).