为什么要重载 << 和 >>
为了更方便的实现复杂对象的输入和输出。
<< 输出运算符重载
他有两种方式:
- 使用成员函数(不推荐,该方式没有实际意义,在这里就不代码演示了)
2. 使用友元函数(极力推荐使用该方式)
使用友元函数重载输出运算符 <<
需求:
- 定义Boy类,Boy类实现输出运算符重载,且使用友元方式;
- 根据Boy类,定义出对象boy1,并赋值Boy boy1(“张三”, 34, 50000);
- 使用友元方式的输出运算符重载输出boy1。
代码示例:
Boy.h
#pragma
#include <iostream>
using namespace std;
class Boy {
public:
Boy(const char *name=NULL, int age=0, int salary=0);
~Boy();
private:
char *name;
int age;
int salary;
// 输出运算符函数 声明为友元
friend ostream &operator<<(ostream &os, Boy &boy);
};
// 函数声明
ostream &operator<<(ostream &os, Boy &boy);
Boy.cpp
#include "Boy.h"
Boy::Boy(const char *name, int age, int salary) {
if (name == NULL) {
name = "无名";
}
this->name = new char[strlen(name)+1];
strcpy_s(this->name, strlen(name)+1, name);
this->age = age;
this->salary = salary;
}
Boy::~Boy() {
if (name) {
delete[] name;
}
}
// 函数实现
ostream &operator<<(ostream &os, Boy &boy) {
os << "姓名:" << boy.name << "\t年龄:" << boy.age << "\t薪资:" << boy.salary;
return os;
}
main
#include "Boy.h"
// 需求:
/* 1.定义Boy类,Boy类实现输出运算符重载,且使用友元方式;
* 2.根据Boy类,定义出对象boy1,并赋值Boy boy1("张三", 34, 50000);
* 3.使用友元方式的输出运算符重载输出boy1.
*/
int main(void) {
Boy boy1("张三", 34, 50000);
// boy.operator(cout);
cout << boy1 << endl;
system("pause");
return 0;
}
运行截图:
>> 输入运算符重载
与输出运算符重载大同小异,这里也是使用友元函数来实现
需求:
- 定义Boy类,Boy类实现输入运算符重载,且使用友元方式;
- 根据Boy类,定义出对象boy2,但不赋值 Boy boy2;
- 给boy2输入数据:“李四” 36 55000;
- 输出boy2的值。
代码示例:
Boy.h
#pragma
#include <iostream>
using namespace std;
class Boy {
public:
Boy(const char *name=NULL, int age=0, int salary=0);
~Boy();
private:
char *name;
int age;
int salary;
// <<输出运算符函数 声明为友元
friend ostream &operator<<(ostream &os, Boy &boy);
// >>输入运算符函数 声明为友元
friend istream &operator>>(istream &in, Boy &boy);
};
// 输出<< 函数声明
ostream &operator<<(ostream &os, Boy &boy);
// 输入>> 函数声明
istream &operator>>(istream &in, Boy &boy);
Boy.cpp
#include <string>
#include "Boy.h"
Boy::Boy(const char *name, int age, int salary) {
if (name == NULL) {
name = "无名";
}
this->name = new char[strlen(name)+1];
strcpy_s(this->name, strlen(name)+1, name);
this->age = age;
this->salary = salary;
}
Boy::~Boy() {
if (name) {
delete[] name;
}
}
// 输出 << 函数实现
ostream &operator<<(ostream &os, Boy &boy) {
os << "姓名:" << boy.name << "\t年龄:" << boy.age << "\t薪资:" << boy.salary;
return os;
}
// 输入 >> 函数实现
istream &operator>>(istream &in, Boy &boy) {
// 原理分析:
// 因为还不知道会输入多少字节给指针name,
// 所以不能直接输入:in >> boy.name >> boy.age >> boy.salary; // error
// 所以得定义一个c++类型的字符串输入值后,再计算出他的长度,
// 再分配对应的字节长度的内存给指针name,最后再把Name 拷贝 给 name。
string Name;
in >> Name >> boy.age >> boy.salary;
// 如果boy.name中原本有内存,那么就释放掉
if (boy.name) {
delete[] boy.name;
}
// 计算出Name一共有多少个字节,再加一(加一字节给回车符)
int line = strlen(Name.c_str())+1;
boy.name = new char[line];
strcpy_s(boy.name, line, Name.c_str());
return in;
}
main
#include "Boy.h"
// 需求:
/* 1.定义Boy类,Boy类实现输入运算符重载,且使用友元方式;
* 2.根据Boy类,定义出对象boy2,但不赋值 Boy boy2;
* 3.给boy2输入数据:"李四" 36 55000;
* 4.输出boy2的值。
*/
int main(void) {
//Boy boy1("张三", 34, 50000);
boy.operator(cout);
//cout << boy1 << endl;
Boy boy2;
cout << "请输入boy2的值:" << endl;
cin >> boy2;
cout << boy2 << endl;
system("pause");
return 0;
}
运行截图:
注意:
1.使用 istream 和 ostream 必须包含头文件 #include < iostream >
2.operator
关键字 必须使用std:: 修饰(声明命名空间也可以:using namspace std;)
总结:
输出<< 运算符重载个人感觉比较实用,学会了以后在工作中可能会用到。