c++基础(4)——操作符重载

一.操作符函数重载

什么是操作符函数:在C++中针对类类型的对象的运算符,由于它们肯定不支持真正的运算操作,因此编译器会将它们翻译成函数,这种就叫做操作符函数(运算符函数)

编译器把运算符编译成运算符函数,可以针对自定义的类类型设计它独有的运算功能

其实各种运算符已经基本一些功能,再次实现它就是叫作运算符重载

双目运算符:
		a+b
		成员函数
			a.operator+(b);
		全局变量
			operator+(a,b);
	单目运算符:
		!a
		成员函数
			a.operator!(void);
		全局函数
			operator!(a);				

二.双目操作符函数重载

成员函数:
		const 类对象 operator #(const) const
		{
			return(参数#参数);
		}
		注意:双目运算符的运算结果是个右值,返回值应该加 const,然后为了const对象能够调用参数应写 const,函数也应该具备const属性
	全局函数:
	constoperator#(const& a,const& b)
	{
	}

注意:全局函数不是成员函数,可能会访问类的私有成员,解决这个问题可以把函数声明为类的友元函数(友元没有this指针,不是成员)

友元:在类的外部某个函数中想访问类的私有成员(public/protected/private)时,需要所在的函数声明为友元,友元只是朋友,因此它只有访问权,没有实际的拥有权(其根本原因是它没有this指针)

友元声明:把函数的声明写一份到类中,然后在声明前加上 friend 关键字

注意:友元函数与成员函数不会构成重载关系,因为它们不在一个作用域,使用友元既可以把操作符定义为全局的,也可以确保类的封装性

三.赋值类型的双目运算符

		成员函数
		 类& operator#(void)
		{
		}	
	全局函数
		 类& operator#(const& that)
		{
		}
		1.获取单参构造成赋值运算的调用方式
			String str="sunll";//会调用单参构造,而不调用赋值构造			
	
		2.左操作数据不能具有const属性
			1.成员函数不能是常函数
			2.全局函数第一个参数不能有const属性

四.单目操作符函数重载

	成员函数
		const& operator#(void)const
		{
		}	
	全局函数
		const& operator#(const& that)	
		{
		}++/--& operator#(void)
		{
			
		}& operator#(& that)
		{
		
		}++/--(哑元)
		const& operator#(int)
		{
			
		}
		const& operator#(& that,int)
		{
		
		}

五.输入输出操作符重载
cout 是ostream类型的对象,cin是istream类型的对象
如果<</>>运算实现位运算函数,那么调用者应该是ostream/istream,而我们无权增加标准库的代码,因此输入/删除运算符只能定义为全局函数
ostream& operator<<(ostream& os,const 类&p)
{
}
istream& operator<<(istream& is,const 类&p)
{
}
注意:在输入输出过程中,cin/cout会记录错误标志,因此不能加const属性
六.特殊操作符的重载
1.下标操作符[ ],常用于在容器类型中以下标获取元素

		类型& operator[](int i)
		{
		}

2.函数操作符(),一个类如果重载函数操作符,那么它的对象就可以像函数一样使用,参数的个数,返回值类,可以不确定,
它是唯一一个可以参数有缺省参数的操作符

3.解引用操作符 ,成员访问操作符->
如果一个类重载了 * 和->,那么它的对象就可以向指针一样使用
所谓的智能指针就是一种类对象,它支持解引用和成员访问操作符

4.智能指针
常规指针的缺点:
当一个常规指针离开它的作用域时,只有该指针所占的空间会被释放,而它指向的内存空间能否被释放就不一定了,
在一些特殊情况(人为,业务逻辑特殊)free或delete没有执行,就会形成内存泄露
智能指针的优点:
智能指针是一个封装了常规指针的类类型对象,当它离开作用域时,它的析构函数就会自动执行,
他的析构函数会负责释放常规指针所指向的动态内存(以正确方式创建的智能指针,它的析构函数才会正确执行)
智能指针和常规指针的相同点:都支持*和->运算
智能指针和常规指针的不同点:
任何时候,一个对象只能使用一个智能指针来指向,而常规指针可以指向多次
智能指针的赋值操作需要通过拷贝构造和赋值构造特殊处理(深拷贝)

auto_ptr:标准库中封装号的智能指针,实现了常规指针的基本功能,
		头文件 #include<memory>
		用法:auto_ptr<指向的类型>指针变量名(对象的地址)
		auto_ptr的局限性:
			不能跨作用域使用,一旦离开作用域指针变量会释放它指向的对象也会释放
			不能放入标准容器
			不能指向对象数据

5.new/delete/new[]/delete[] 运算符
1.C++中缺省的动态内存管理器速度较慢,重载new/delete底层使用malloc/free可以提高运行速度

2.new 在失败时会产生异常,而每次使用new时为了安全都应该进行异常捕获,而重载new操作符只需要在操作符函数中进行一次错误处理即可

3.在一些占字节数比较小的类,频繁使用new,可能会产生大量的内存碎片, 而重载new操作符后,可以适当的扩大每次申请的字节数,减少内存碎片产生的几率

4.重载 new/delete可以记录栈内存使用的信息

5.重载delete可以检查到释放内存释放失败的信息,检查到内存泄露

七.重载操作符的限制

1.不能重载的重载符
域限定符::
直接成员访问操作符 .
三目运算符?:
字节长度操作符sizeof
类型信息操作符typeid

2.重载操作符不能修改操作符的优先级

3.无法重载所有基本类型的操作符运算

4.不能修改操作的参数个数

5.不能发明新的操作符

关于操作重载的建议:
1.在重载操作符的时候要根据操作符实际的功能和意义来确定具体参数,返回值,是否具有const属性,返回值是否是引用或是临时对象

2.重载操作符要符合情理(要有意义),要以实际用途为前提

3.重载操作符的意义是为了让对象的操作更简单,方便,而不是为了炫技

4.重载操作符要与默认的操作符的功能,运算规则一致,不要出反人类的操作

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值