C++ 操作符重载

本文介绍了C++中的运算符重载,特别是关于输出操作符"<<"和输入操作符">>"的重载。讨论了如何重载这些运算符以处理内置类型和自定义类型的数据,以及为何需要将重载函数设为友元函数。通过代码实例和分析,展示了如何改进运算符重载以简化输出自定义类型如复数和分数的操作。
摘要由CSDN通过智能技术生成

输出操作符"<<" 和输入操作运算符">>"

操作符重载,也叫运算符重载,是C++的重要组成部分,它可以让程序更加的简单易懂,简单的运算符使用可以使复杂函数的理解更直观。

操作符重载可对 已有的运算符(C++中预定义的运算符)赋予多重的含义,是一种用于同一运算符作用于不同类的数据时可以导致有不同类型的行为(多态)

一个操作符被能重载的基本前提是:
1.只能为用户自定义的类型进行操作符的重载
2.不能对操作符的语法(优先级,结合性,操作数个数,语法结构,语义) 进行颠覆。
3.不能重载新的自定义操作符

在C++中,左移运算符<<可以和cout一起输出,因此也常被称为"流插入操作符",或"输出操作符"。 但实际上!<<本来没有这样的功能,之所以能和cout一起使用来输出数据,是因为此<<操作符被重载

在C++中,标准库本身已经对左移运算符<<和右移运算符>>分别进行了多次重载,使其能够用于不同数据的输入输出,但是输入输出的对象只能是 C++ 内置的数据类型(例如 bool、int、double 等)和 标准库所包含的类类型(例如 stringcomplexofstreamifstream 等)


重载"<< >>"输入和输出C++内置的数据类型

cout类与输出操作符"<<"的重载:

cout是ostream类的对象,ostream类和cout都是在头文件 <iostream>中声明的,ostream类将<<重载为其成员函数,而且重载多次,例如,为了使 [cout<<"hello world"] 能够成立,程序便重载了<<操作符用于输出char类型数据,具体来看,ostream需要对<<操作符进行以下重载操作:

ostream &ostream::operator<<(const char *s)
{
    
	//...输出s的代码
	return	*this;
}

为了使 [out<<5] 能够成立(重载<<操作符用于输出int类型数据),ostream 类还需要将<<进行如下重载操作:

ostream & ostream::operator << (int n)
{
   
	//...输出n的代码
    return *this;函数返回当前对象*this指针(当前对象的值的地址)
}

以上述代码为例:
重载操作符函数的返回值类型为ostream的引用(ostream&),并且函数返回当前对象*this指针(当前对象的值的地址),就使得 [cout<<"hello world"<<5] 能够成立。

有了上方的重载函数进行<<操作符的重载 [cout<<"hello world"<<5]就等价于:[cout.operator<<("hello world")).operator<<(5)]

重载函数返回*this,使cout<<"hello world"这个表达式的值依然是cout(更准确的说法是cout的引用,等价于cout),所以能和<<5继续进行运算

cin类与输出操作符">>"的重载:

cin是istream类的对象,是在头文件<iostream>中声明的。istream类>>重载为成员函数,因此cin才能和>>进行联用以输入数据,一般也将>>称为 流提取操作符或者输入操作符


重载"<< >>"符用于输入和输出用户自己定义的类型的数据

例题:假定a,b,c是Comlex复数类对象,现在希望程序输入cin>>a>>b,便能从键盘接收a和b复数形式的输入(输入两个复数),写入cout<<c就能以a+b的形式输出a,b两个复数的和(c的值)。

代码演示:

#include <iostream>

using namespace std;

//todo案例一:假定c是Comlex复数类对象, 现在希望写cout << c; 就能以a + bi的形式输出c的值, 写cin >> c, 就能从键盘接收a + bi形式的输入,并使得c.real = a, c.imag = b;

class Comlex
{
   
public:
	double real, imag;

	//Comlex类构造器
	Comlex(double r=0, double i=0) :real(r), imag(i) {
   };
	🔥Comlex的类构造器的形式列表中的两个形参因为需要进行覆盖输入,所以要设置两个参数的默认值为0,设置了默认值后,
	在构建Complex类的对象 a 时 ,就可以写成 Complex a ;而无需给对象a添加参数列表
	
	🔥为什么在构造器形参列表后面加上冒号:
	其实冒号后的内容(:real(r), imag(i))是初始化值,意为传入的形参数据用来初始化类成员,相当于:
	//	Comlex(double r=0, double i=0) 
	//	{
   
	//		real(r)
	//		imag(i)
	//	}

	Comlex operator +(Comlex& c);//"+"号运算符的重载函数声明(用于复数的计算
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值