C++运算符重载技术

前言:C++语言给使用提供重载机制,大大提高的使用的灵活性。

1 函数重载概念

函数重载概念
函数重载(Function Overload)

  • 用同一个函数名定义不同的函数
  • 当函数名和不同的参数搭配时函数的含义不同

函数重载的判断标准

  1. 函数中参数个数不同
  2. 函数中参数类型不同
  3. 函数中参数顺序不同

注意:
不能把返回值作为函数重载的条件,原因是编译器在编译时不会去判断函数的返回类型,函数只有调用后,编译器才会去验证返回类型,所以返回值不能作为函数重载的依据。

常函数 const 可以作为函数重载判断依据,原因:重载[]运算符时,有没有const的区别是:有const只读,没有const读写都可以。

所谓重载,就是重新赋予新的含义。函数重载就是对一个已有的函数赋予新的含义,使之实现新功能,因此,一个函数名就可以用来代表不同功能的函数,也就是”一名多用”。

运算符也可以重载。实际上,我们已经在不知不觉之中使用了运算符重载。例如,大 家都已习惯于用加法运算符”+”对整数、单精度数和双精度数进行加法运算,如5+8, 5.8 +3.67等,其实计算机对整数、单精度数和双精度数的加法操作过程是很不相同的, 但由于C++已经对运算符”+”进行了重载,所以就能适用于int, float, doUble类型的运算。

又如”<<“是C++的位运算中的位移运算符(左移),但在输出操作中又是与流对 象cout 配合使用的流插入运算符,”>>“也是位移运算符(右移),但在输入操作中又是与流对象 cin 配合使用的流提取运算符。这就是运算符重载(operator overloading)。C++系统对”<<“和”>>“进行了重载,用户在不同的场合下使用它们时,作用是不同 的。对”<<“和”>>“的重载处理是放在头文件stream中的。因此,如果要在程序中用”<< “和”>>”作流插入运算符和流提取运算符,必须在本文件模块中包含头文件stream(当然还应当包括”using namespace std“)。

现在要讨论的问题是:用户能否根据自己的需要对C++已提供的运算符进行重载,赋予它们新的含义,使之一名多用。?

2 运算符重载入门技术推演

为什么会用运算符重载机制,这样可以大大提高代码的可读性可灵活性!
我们举一个例子:
复数类举例
Complex c3 = c1 + c2; 这个语句这个编译器无法编译通过。因为编译器是无法知道这个+是执行什么,但是编译器给提供了一种机制,让用户自己去完成,自定义类型的加减操作,符号运算,这个机制就是运算符重载机制

运算符重载的本质是一个函数

#include <iostream>
using namespace std;

class Complex
{
public:
	int real;  //复数实部
	int imaginary; //复数虚部
public:
	Complex(int real = 0, int imaginary = 0)
	{
		this->real = real;
		this->imaginary = imaginary;
	}

public:
	void printComplex()
	{
		cout << real << " + " << imaginary << "i " << endl;
	}
};

Complex operator+(Complex& c1, Complex& c2)
{
	Complex tmp(c1.real + c2.real, c1.imaginary + c2.imaginary);
	return tmp;
}

void main()
{
	Complex c1(1, 2), c2(3, 4);
	Complex c3 = c1 + c2; //思考C++编译器如何支持操作符重载机制的 (根据类型)
	c3.printComplex();
	system("pause");
	return;
}

输出结果:
在这里插入图片描述
这个就是通过我们设置一个全局函数满足了自定义复数+运算。所以运算符重载的本质是一个函数 另外也可以通过成员函数和友元函数的形式实现符号重载。
全局函数建议使用友元函数在类中定义保证类的封装低耦合。

这样存在一个细节问题:是不是所有的符号都可以进行符号重载,答案是否定的。
在这里插入图片描述在这里插入图片描述
运算符重载的两种方法

  • 运算符函数可以重载为成员变量或者友元函数
  • 关键不同在于成员函数隐含着this指针,友元函数不含有this指针
  • 不管是成员函数还是友元函数的符号重载,运算符的方法相同。但是传递参数的方法不同,实现的代码的方式也不同。
    上面的复数加法的实现也可以如下:
#include <iostream>
using namespace std;

class Complex
{
private:
	int real;  //复数实部
	int imaginary; //复数虚部
public:
	Complex(int real = 0, int imaginary = 0)
	{
		this->real = real;
		this->imaginary = imaginary;
	}

public:
	void printComplex()
	{
		cout << real << " + " << imaginary << "i " << endl;
	}
	Complex operator+(Complex& c2)
	{
		Complex tmp(this->real + c2.real, this->imaginary + c2.imaginary);
		return tmp;
	}
};

//Complex operator+(Complex& c1, Complex& c2)
//{
//	Complex tmp(c1.real + c2.real, c1.imaginary + c2.imaginary);
//	return tmp;
//}

void main()
{
	Complex c1(1, 2), c2(3, 4);
	Complex c3 = c1 + c2; //思考C++编译器如何支持操作符重载机制的 (根据类型)
	c3.printComplex();
	system("pause");
	return;
}
前置和后置运算符总结

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

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

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

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

友元函数和成员函数选择方法

  • 当无法修改左操作数的类时,使用全局函数进行重载
  • =, [], ()和->操作符只能通过成员函数进行重载

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

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

3)友元函数重载操作符使用注意点
友员函数重载运算符常用于运算符的左右操作数类型不同的情况
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值