C++面向对象编程(五)之 运算符重载

本文详细解释了C++中运算符重载的概念、语法、应用场景,并通过实例展示了如何实现运算符重载,包括全局函数法、类成员函数法、友元函数法,以及如何使用运算符重载解决实际问题。

运算符重载:

用户根据自己的需要对C++以提供的运算符进行重载,赋予新的含义,使之一名多用。


运算符重载的本质是,函数调用。


重载运算符的函数一般格式如下:


类型  类名::  operator 运算符名称(形参列表)  // 这里 应该把(operator 运算符名称) 看成是函数名


说明:

一个运算符被重载后,原有的意义没有失去,只是定义了相对一特定类的一个新的运算符。

不能重载的运算符    .     ::       .*   ?:        sizeof

运算符函数可以重载为成员函数 或者友元函数

关键区别在于成员函数具体this指针,友元函数没有this指针。


定义运算符重载函数名的步骤

全局函数、类成员函数方法实现运算符重载步骤:

  • 要承认操作符重载是一个函数,写出函数名 operator + ()
  • 根据操作数,写出函数参数
  • 根据业务,完善函数返回值(看函数返回引用?还是指针?还是对象),实现业务函数


#include <iostream>
using namespace std;

class Complex
{
private:
	int a;
	int b;
	friend Complex operator+(Complex &c1,Complex &c2);
	friend Complex& operator++(Complex &c1);
	friend Complex operator++(Complex &c1,int);
public:
	Complex(int a=0, int b=0)
	{
		this->a = a;
		this->b = b;
	}
	void printCom()
	{
		cout << a << " + " << b << "i" <<endl;
	}
	//
	Complex operator-(Complex&c2)
	{
		Complex tmp(this->a - c2.a,this->b - c2.b);
		return tmp;
	}
	Complex& operator--()
	{
		this->a --;
		this->b --;
		return *this;
	}
	//后置--
	Complex operator--(int)
	{
		Complex tmp = *this;
		this->a--;
		this->b--;
		return tmp;
	}
};

 

//函数名为operator+  1 全局函数法 实现 + 运算符重载
Complex operator+(Complex &c1,Complex &c2)
{
	Complex tmp(c1.a + c2.a, c1.b + c2.b);
	return tmp;
}
Complex& operator++(Complex &c1)
{
	c1.a++;
	c1.b++;
	return c1;
}

Complex operator++(Complex &c1,int)
{
	Complex tmp = c1;
	c1.a++;
	c1.b++;
	return tmp;
}

int main()
{
	Complex c1(1,2),c2(3,4);

	Complex c3 = c1 + c2;
	c3.printCom();
	//1 全局函数法(友元函数法) 实现 + 运算符重载
	//函数名为operator+ 
	//Complex operator+(Complex &c1,Complex &c2)
	 
	//2 类成员函数法 实现 - 运算符重载
	//c1.operator-(c2) //调用方式
	//Complex operator-(Complex&c2) //左操作数(左边形参)是通过this指针传递,因此不用写。
	Complex c4 = c1 - c2;
	c4.printCom();

	//前置++操作符,用全局函数法实现。
	//Complex& operator++(Complex &c1);
	++c1;
	c1.printCom();

	//前置--操作符,用类成员函数方法
	--c1;
	c1.printCom();
	//后置++操作符,用全局函数法实现 ,C++编译器使用函数占位参数以区别前置++
	//同理后置减减操作符,同样也使用函数占位参数区别前置——
	//Complex operator++(Complex &c1,int)
	c1++;
	c1.printCom();
	c1--;
	c1.printCom();
	//c1.operator--(c2)
	//Complex operator--(int)
	system("pause");
	return 0;
}

C++中通过一个占位参数来区分前置运算和后置运算。

(带有占位参数的运算符重载函数,代表是后置的运算符,如后置++,或者后置--)


友元函数实现操作符重载的应用场景:

 当无法修改左操作数的类时,使用全局函数(通常设置为友元)进行重载。

      友元函数重载运算符常用于运算符的左右操作数类型不同的情况。

例如用友元函数重载 <<  >>  操作符。

  •      istream和ostream是C++预定义的流类
  •      cin是istream的对象,cout是ostream的对象
  •      运算符 << 由ostream 重载为插入操作,用于输出基本类型数据
  •       运算符 >> 由 istream 重载为提取操作,用于输入基本类型数据
  •       用友元函数重载 << 和 >> ,输出和输入用户自定义的数据类型。

#include <iostream>
using namespace std;
class Complex
{
private:
	int a;
	int b;
	friend ostream& operator<<(ostream &out, Complex &c1);

public:
	Complex(int a=0, int b=0)
	{
		this->a = a;
		this->b = b;
	}
	void printCom()
	{
		cout<<a<<" + " << b << "i" <<endl;
	}
public:

	//实现 + 运算符重载
	Complex operator+(Complex &c2)
	{
		Complex tmp(a + c2.a, b + c2.b);
		return tmp;
	}

	//前置++
	Complex& operator++()
	{
		a++;
		b++;
		return *this;
	}

	//后置++
	Complex operator++(int)
	{
		//先使用 在让c1加加
		Complex tmp = *this;
		//return c1;
		this->a ++;
		this->b ++;
		return tmp;
	}
	//成员函数法 实现 -运算符重载
	 Complex operator-(Complex &c2)
	{
		Complex tmp(this->a - c2.a, this->b - c2.b);
		return tmp;
	}

	 //前置--
	Complex& operator--()
	{
		this->a --;
		this->b --;
		return *this;
	}

	//后置--
	Complex operator--(int)
	{
		Complex tmp = *this;
		this->a--;
		this->b--;
		return tmp;
	}
};

ostream& operator<<(ostream &out, Complex &c1)
{
	out<<"12345 生活真是苦"<<endl;
	out<<c1.a << " + " << c1.b << "i" << endl;
	return out;
}

void main()
{
	int a = 10;
	Complex c1(1, 2), c2(3, 4);
	cout<<a<<endl; //按照数据类型 

	//1
	cout << c1 ;
	//2 ostream 类中 添加 成员函数 .operator<<
	//ostream
	//cout.operator<<(c1);

	//2 函数返回值当左值 需要返回一个引用
	cout << c1  << "aaddddd"; //连续输出
	//
	//cout.operator<<(c1) .operator<<("aaddddd");
	//void.operator<<("aaddddd");

	system("pause");
}


结论是:函数返回当左值,必须返回一个引用。而且返回一个引用可以实现链式编程。



  =, [], ()和->操作符只能通过成员函数进行重载 


重载等号=操作符。

  1. 先释放旧的内存,防止内存泄露。
  2. 返回一个引用,支持链式编程。


重载[]操作符,

返回一个引用,因为通常把它作为左值。


重载函数调用符() 可以实现数学函数的抽象


为什么不要重载&& 和 || 操作符


说明:

  • &&和|| 是C++中非常特殊的操作符
  • &&和|| 内置实现了短路规则
  • 操作符重载是靠函数重载来完成的
  • 操作数作为函数参数传递
  • C++的函数参数都会被求值,无法实现短路规则

运算符重载在项目开发中的应用:


实现一个数组类

实现一个字符类



总结

操作符重载是C++的强大特性之一

操作符重载的本质是通过函数扩展操作符的语义

operator关键字是操作符重载的关键

friend关键字可以对函数或类开放访问权限

操作符重载遵循函数重载的规则

操作符重载可以直接使用类的成员函数实现

=,[ ] ,()和->操作符只能通过成员函数进行重载

++操作符通过一个int参数(占位参数)进行区别前置与后置的重载

C++中不要重载&& 和 || 操作符 



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值