我在学习c++输入输出的重载的一些心得,给大家分享一下,有问题的地方欢迎大家指出来~
先上代码:
#include<iostream>
using namespace std;
class Complex{
private:
int id;
int real;
int image;
public:
Complex(int _real=0, int _image=0, int _id=0); // 构造函数
~Complex(); // 析构函数
friend ostream& operator<<(ostream &out, const Complex& c);
friend istream& operator>>(istream &in, Complex &c);
};
Complex::Complex(int _real, int _image, int _id) : real(_real), image(_image), id(_id) {}
Complex::~Complex() {
cout << "Destroyed." << endl;
}
ostream& operator<<(ostream &out, const Complex& c) {
out << c.id << " " << "Complex:" << c.real << "+" << c.image << "i" << endl;
return out;
}
istream& operator>>(istream &in, Complex &c) {
in >> c.id >> c.real >> c.image;
return in;
}
int main() {
Complex a,b;
cout << a;
cout << "分割线" << endl;
cin >>b ;
cout << b;
return 0;
}
现在进行说明:
当我们在c++中创建了一个类后,通常需要通过成员函数来打印类中的数据成员,如上面的Complex类
class Complex{
private:
int id;
int real;
int image;
}
现在定义一个Complex a;
直接cout<<a;
显然报错,因为a是一个类,不是c++输入输出流能够输出的数据类型,所以我们需要对输入输出符进行重载,通常对>>,<<的重载我们以友元函数来进行,这是因为这样编写代码更符合我们的阅读习惯,如果是通过成员函数来进行重载,调用函数的时候需要如下
a<<cout<<endl;
显然不符合我们的编写习惯;
输出重载的形式式如下
friend ostream& operator<<(ostream &out, const Complex& c) { out<<c.real; return out; }
输入重载的形式如下
friend istream& operator>>(istream &in, Complex &c) { in>>c.real; return in; }
上面两个都是以本文的Complex类为例子的,函数的第一个参数是输入或者输出流的引用,第二个参数是类的引用,这是因为 istream
类的对象不允许被复制。istream
类的设计原则是每个输入流对象都应该是独一无二的,因为它们通常与设备或文件相关联,复制这些对象可能会导致资源管理上的问题。因此,istream
类的拷贝构造函数和拷贝赋值运算符都是删除的(private且未定义),这意味着你不能创建 istream
对象的副本。
使用引用作为 operator>>
的参数,可以避免复制 istream
对象,同时允许你的函数直接操作传入的输入流对象。此外,使用引用还有助于保持性能,因为它避免了不必要的数据复制。
当 operator>>
函数返回 istream &
时,它通常返回对输入流对象的引用,这样可以支持链式输入操作。链式输入操作允许你在一行代码中连续调用多个输入操作符,例如 cin >> x >> y >> z;
,其中每个 >>
操作符都会返回它操作的输入流对象的引用,从而允许下一个 >>
操作符继续在同一个输入流上进行操作