服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C/C++ - C++ 流插入和流提取运算符的重载的实现

C++ 流插入和流提取运算符的重载的实现

2021-08-06 15:23小林coding C/C++

这篇文章主要介绍了C++ 流插入和流提取运算符的重载的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

01 流插入<<运算符的重载

C++ 在输出内容时,最常用的方式:

?
1
std::cout << 1 <<"hello";

问题:

  • 那这条语句为什么能成立呢?
  • cout 是什么?"<<" 运算符能用在 cout 上呢?

原因:

  • 实际上,cout 是在 iostream 头文件中定义的 ostream 类的对象。
  • "<<" 能够用在 cout 上是因为,在 ostream 类对 "<<" 进行了重载。

对于std::cout << 1 <<"hello";这条语句,有可能按以下的方式重载成 ostream 类的成员函数:

?
1
2
3
4
5
6
7
8
9
10
11
ostream & ostream::operator<<(int n)
{
  .... // 输出n整型的代码
  return *this;
}
 
ostream & ostream::operator<<(const char * s)
{
  .... // 输出s字符串的代码
  return *this;
}
  • std::cout << 1;语句,等价于cout.operator<<(1);
  • std::cout << "hello";语句,等价于cout.operator<<("hello");
  • std::cout << 1 <<"hello";语句,等价于( cout.operator<<(1) ).operator<<("hello");

02 流插入<<运算符重载的例子

假定我们要想把某个对象里的内容进行打印输出,那么我们可以重载 ostream 类的流插入 << 运算符。

下面以 CStudent 类作为例子:

?
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
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,20,小林coding

需要注意是 ostream & operator<<(ostream & o, const CStudent & s) 函数是全局的,所以函数的第一个参数必须要传入 ostream 的对象,并且 CStudent 类需要将此函数声明成友元函数,使得函数可以访问 CStudent 类的私有成员变量。

03 流提取>>运算符重载的例子

还是以 CStudent 类作为例子,假设想通过键盘的输入的内容,来初始化对象,则我们可以重载 istream 类的流提取 >> 运算符。

?
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
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,20,小林coding

// 输出内容:
1,20,小林coding

04 小结

要想流插入 << 运算符和流提取 >> 运算符能针对自定义的对象,那么我们就需要重载针对该对象的 ostream 类的 << 运算符 和 istream 的 >> 运算符,并且只能重载成全局的函数,然后在 CStudent 类里需要把上面的两个重载函数声明成友元函数,使得两个重载的函数可以访问和赋值 CStudent 类里的私有成员函数。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:https://segmentfault.com/a/1190000021175952

延伸 · 阅读

精彩推荐
  • C/C++OpenCV实现拼接图像的简单方法

    OpenCV实现拼接图像的简单方法

    这篇文章主要为大家详细介绍了OpenCV实现拼接图像的简单方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    iteye_183805102021-07-29
  • C/C++关于C语言中E-R图的详解

    关于C语言中E-R图的详解

    今天小编就为大家分享一篇关于关于C语言中E-R图的详解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看...

    Struggler095962021-07-12
  • C/C++C语言main函数的三种形式实例详解

    C语言main函数的三种形式实例详解

    这篇文章主要介绍了 C语言main函数的三种形式实例详解的相关资料,需要的朋友可以参考下...

    ieearth6912021-05-16
  • C/C++使用C++制作简单的web服务器(续)

    使用C++制作简单的web服务器(续)

    本文承接上文《使用C++制作简单的web服务器》,把web服务器做的功能稍微强大些,主要增加的功能是从文件中读取网页并返回给客户端,而不是把网页代码...

    C++教程网5492021-02-22
  • C/C++c/c++内存分配大小实例讲解

    c/c++内存分配大小实例讲解

    在本篇文章里小编给大家整理了一篇关于c/c++内存分配大小实例讲解内容,有需要的朋友们可以跟着学习参考下。...

    jihite5172022-02-22
  • C/C++深入C++拷贝构造函数的总结详解

    深入C++拷贝构造函数的总结详解

    本篇文章是对C++中拷贝构造函数进行了总结与介绍。需要的朋友参考下...

    C++教程网5182020-11-30
  • C/C++c/c++实现获取域名的IP地址

    c/c++实现获取域名的IP地址

    本文给大家汇总介绍了使用c/c++实现获取域名的IP地址的几种方法以及这些方法的核心函数gethostbyname的详细用法,非常的实用,有需要的小伙伴可以参考下...

    C++教程网10262021-03-16
  • C/C++C语言实现双人五子棋游戏

    C语言实现双人五子棋游戏

    这篇文章主要为大家详细介绍了C语言实现双人五子棋游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    两片空白7312021-11-12