C++ 流插入和流提取运算符的重载
01 流插入<<运算符的重载
C++ 在输出内容时,最常用的方式:
std::cout << 1 <<"hello";
- 1
问题:
- 那这条语句为什么能成立呢?
cout
是什么?"<<
" 运算符能用在cout
上呢?
原因:
- 实际上,
cout
是在iostream
头文件中定义的ostream
类的对象。 - “
<<
” 能够用在cout
上是因为,在ostream
类对 “<<
” 进行了重载。
对于std::cout << 1 <<"hello";
这条语句,有可能按以下的方式重载成 ostream
类的成员函数:
ostream & ostream::operator<<(int n)
{ .... // 输出n整型的代码 return *this;
}
ostream & ostream::operator<<(const char * s)
{ .... // 输出s字符串的代码 return *this;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
std::cout << 1;
语句,等价于cout.operator<<(1);
std::cout << "hello";
语句,等价于cout.operator<<("hello");
std::cout << 1 <<"hello";
语句,等价于( cout.operator<<(1) ).operator<<("hello");
02 流插入<<运算符重载的例子
假定我们要想把某个对象里的内容进行打印输出,那么我们可以重载 ostream
类的流插入 <<
运算符。
下面以 CStudent
类作为例子:
class CStudent // 学生类
{
public: // 构造函数 CStudent(int id = 0, int age = 0, string name = ""):m_id(id), m_age(age), m_name(name) { } // 将该函数声明成友元函数 // 目的是使得函数可以访问CStudent类的私有成员变量 friend ostream & operator<<(ostream & o, const CStudent & s); private: int m_age; // 年龄 int m_id; // ID号 string m_name; // 名字
};
// 重载ostream对象的流插入<<运算符函数
// 目的是使得能打印输出CStudent对象的信息
ostream & operator<<(ostream & o, const CStudent & s)
{ o << s.m_id << "," << s.m_age << "," << s.m_name; return o;
}
int main()
{
CStudent stu(1, 20, "小林coding");
std::cout << stu ; // 输出std对象的全部信息 return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
输出结果:
1,20,小林coding
- 1
需要注意是 ostream & operator<<(ostream & o, const CStudent & s)
函数是全局的,所以函数的第一个参数必须要传入 ostream
的对象,并且 CStudent
类需要将此函数声明成友元函数,使得函数可以访问 CStudent
类的私有成员变量。
03 流提取>>运算符重载的例子
还是以 CStudent
类作为例子,假设想通过键盘的输入的内容,来初始化对象,则我们可以重载 istream
类的流提取 >>
运算符。
class CStudent // 学生类
{
public: // 构造函数 CStudent(int id = 0, int age = 0, string name = ""):m_id(id), m_age(age), m_name(name) { } // 将该函数声明成友元函数 // 目的是使得函数可以访问CStudent类的私有成员变量 friend ostream & operator<<(ostream & o, const CStudent & s); // 将该函数声明成友元函数 // 目的是使得函数可以给CStudent类的私有成员变量进行赋值 friend istream & operator>>(istream & is, CStudent & s); private: int m_age; // 年龄 int m_id; // ID号 string m_name; // 名字
};
// 重载ostream对象的流插入<<运算符函数
// 目的是使得能打印输出CStudent对象的信息
ostream & operator<<(ostream & o, const CStudent & s)
{ o << s.m_id << "," << s.m_age << "," << s.m_name; return o;
}
// 重载istream对象的流提取>>运算符函数
// 目的是使得初始化CStudent对象的内容
istream & operator>>(istream & is, CStudent & stu)
{ string inputStr; is >> inputStr; int pos = inputStr.find(",", 0); // 查找首次出现逗号的位置 string tmpStr = inputStr.substr(0, pos); // 截取从0到pos位置的字符串 stu.id = atoi(tmpStr.c_str()); // atoi可以将char*类型的内容转成int类型 int pos2 = inputStr.find(",", pos + 1); // 查找第二次出现逗号的位置 tmpStr = inputStr.substr(pos + 1, pos2 - pos -1); // 取出age的值 stu.age = atoi(tmpStr.c_str()); // atoi可以将char*类型的内容转成int类型 tmpStr = inputStr.substr(pos2 + 1, inputStr.length() - pos2 - 1); // 取出name的值 stu.name = tmpStr; return is;
}
int main()
{ CStudent stu; // 将输入的信息,初始化stu对象 cin << stu; // 输出std对象的信息 cout >> stu; return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
输入内容和输出内容:
// 输入内容:
1,20,小林coding
// 输出内容:
1,20,小林coding
- 1
- 2
- 3
- 4
- 5
04 小结
要想流插入 <<
运算符和流提取 >>
运算符能针对自定义的对象,那么我们就需要重载针对该对象的 ostream
类的 <<
运算符 和 istream
的 >>
运算符,并且只能重载成全局的函数,然后在 CStudent
类里需要把上面的两个重载函数声明成友元函数,使得两个重载的函数可以访问和赋值 CStudent
类里的私有成员函数。
文章来源: blog.csdn.net,作者:小林coding,版权归原作者所有,如需转载,请联系作者。
原文链接:blog.csdn.net/qq_34827674/article/details/103346491
- 点赞
- 收藏
- 关注作者
评论(0)