运算符重载 - 为什么编译器C++不为类提供重载插入器和提取器函数?

operator overloading - Why C++ compiler doesn't provide overloaded inserter & extractor functions for class?

本文关键字:重载 插入 提取 函数 为什么 编译器 C++ 运算符      更新时间:2023-10-16

考虑以下程序。

#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;
}

我故意注释掉了重载的>> && 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')*

默认情况下,即使是空类,如果程序员没有提供,编译器也会自动提供以下内容。

1)构造函数

2)析构函数3)复制构造函数

4) =(赋值)操作符

那为什么呢>> && lt; & lt;操作符必须由程序员显式重载才能使用用户定义的类型(类)?如果编译器默认提供重载>> && lt; & lt;用户定义类型的操作符函数也?这难道不是减少了编写&减轻程序员的负担?

那为什么呢>> && lt; & lt;操作符必须由程序员显式重载才能使用用户定义的类型(类)?

您列出的默认值都不提供序列化或反序列化,这是两个非常复杂的问题,通常难以解决。

您列出的所有四种东西都允许在语义上重新排序它们的操作,但是序列化/反序列化不允许。

另外,序列化的数据应该采用什么格式?二进制还是文本?数据字段之间应该用什么分隔符?数据字段应该命名还是简单排序?

最后,最初的四个都不会失败,然而istream有很多原因。失败了怎么办?是返回部分初始化和部分默认的类,还是抛出异常?

这并不是说这一系列问题是无法回答的,而是答案取决于你其余的代码在做什么,所以一个通用的答案是不可能的。很多地方都希望能够保存他们的数据,所以一个紧凑的二进制表示是很好的。其他地方希望能够轻松地向用户显示数据结构,这需要文本表示。

此外,到目前为止,反对这个想法的最大因素是添加功能的固有成本。这是关于这个话题的答案(有一些关于这个话题的更全面的博客文章,但我没有现成的链接,抱歉)