考虑以下计划。
#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;
}
我故意注释掉了重载的&gt;&gt; &安培; &LT;&LT;运算符函数定义和编译器提供以下错误消息
*[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')*
默认情况下,即使对于空类,如果程序员不提供它们,C ++编译器也会自动提供以下内容。
1)构造函数
2)析构函数
3)复制构造函数
4)=(assigment)运算符
那么为什么&gt;&gt; &安培; &LT;&LT;运算符必须由程序员显式重载才能使用用户定义的类型(类)?如果编译器默认提供重载&gt;&gt;那会不是很好&安培; &LT;&LT;用户定义类型的运算符函数也?这不会减少编写和编写所需的代码吗?减轻程序员的负担?
答案 0 :(得分:3)
那么为什么&gt;&gt; &安培; &LT;&LT;运算符必须由程序员显式重载才能使用用户定义的类型(类)?
您列为默认值的所有内容都不提供序列化或反序列化,这是一般要解决的两个非常复杂的问题。
您列出的所有四件事都允许在语义上对其操作重新排序,但序列化/反序列化不能。
此外,序列化数据应采用何种格式?二进制还是文字?数据字段之间应该有什么分隔符?数据字段应该命名还是只是命令?
最后,原来的四个都不会失败,但istream
可能由于多种原因而失败。失败后你会怎么做?你是否返回了部分初始化和部分默认的类,或者你是否抛出异常?
这一系列问题是无法回答的,答案取决于你的其他代码在做什么,所以一般的答案是不可能的。许多地方希望能够为后者保存他们的数据,因此紧凑的二进制表示是好的。其他地方希望能够轻松地向用户显示数据结构,这需要文本表示。
此外,到目前为止,反对这一想法的最大因素是添加功能的固有成本。 This is answer on that topic(有一些关于这个主题的更全面的博客文章,但我没有一个方便的抱歉)。