C++各类运算符的重载(单双目、输入输出、前++、后++)

一、运算符重载

​ 在C++中会把运算符当做函数来处理 ,当我们使用运算符时,编译器其实是把运算符翻译成函数,由于C++支持函数重载,所以C++中的运算符也是可以重载的,这样可以对类对象进行定制操作,从而简化操作、提高代码的可读性,如:string类就是一个支持众多运算符的字符串类。

​ A a,b;

​ 当对象支持+运算符时:a+b;

成员函数:
const A& operator+(cosnt A& b);
全局函数:
const A& operator+(const A& a,const B& b);

二、双目运算符重载

​ 双目运算符重载的运算结果是一个临时对象,所以返回值应该加const。

成员函数:
const A operator#(const A& b)const
{
    return(a参数#b参数);
}
全局函数:
const A operator#(const A& b,const B& b)
{
    return(a参数#b参数);
}
#include <iostream>
using namespace std;

class Point
{
	int x;
	int y;
public:
	Point(int x,int y):x(x),y(y) {}
	void show(void)const
	{
		cout << "(" << x << "," << y << ")" << endl; 
	}
/*
	const Point operator+(const Point& that)const
	{
		return Point(x+that.x,y+that.y);
	}
	*/
	friend const Point operator+(const Point& a,const Point& b);
};

const Point operator+(const Point& a,const Point& b)
{
	return Point(a.x+b.x,a.y+b.y);
}

int main(int argc,const char* argv[])
{
	Point p(1,1);
	Point p1(2,3);
	p.show();
	(p+p1).show();
}

​ 注意:全局运算符函数中可能会访问到类的私有、保护的成员变量,C++提供的解决方法是把全局运算符函数声明为类的友元函数,那么在友元函数中就可以访问到类的私有、保护类的成员。

友元

​ 在类的外部某个函数中想访问类的私有、保护类的成员函数,需要把函数声明为类的友元函数,但友元仅仅是朋友,它只有访问权没有拥有权(没有this指针)

友元声明

​ 把函数的声明写到类中一份,并在函数的声明前面加上friend关键字,使用引用友元可以确保类的封装性。

注意:友元函数不会与成员函数构成重载,因为它们不在一个作用域内,但依然会冲突

☆三、输入输出运算符重载

  1. cout是ostream类型对象,cin是istream类型对象。
  2. 当我们想让一种类型方便地使用cin/cout运算符时,就需要把它们重载。
  3. 根据双目运算符的解析规则,如果重载为成员函数,则函数调用者为cin/cout,但我们无法到istream/ostream类中修改代码,因此从只能重载为全局函数。
ostream& operator<<(ostream& os,const A a)
istream& operator>>(istream& is,A& a)
#include <iostream>
using namespace std;

class Point
{
	int x;
	int y;
public:
	Point(int x,int y):x(x),y(y) {}
	void show(void)const
	{
		cout << "(" << x << "," << y << ")" << endl; 
	}
	const Point operator+(const Point& that)const
	{
		return Point(x+that.x,y+that.y);
	}

	friend ostream& operator<<(ostream& os,const Point p);
	friend istream& operator>>(istream& is,Point& p);
};

ostream& operator<<(ostream& os,const Point p)
{
	return os << "(" << p.x << "," << p.y << ")";
}

istream& operator>>(istream& is,Point& p)
{
	cout << "输入x的值:";
	is >> p.x ;
	cout << "输入y的值:";
	return is >> p.y;
}

int main(int argc,const char* argv[])
{
	Point p(1,1);
	Point p1(2,3);
	p.show();
	(p+p1).show();
	cout << "-----------------" << endl;
	cout << p << p1 << endl;
	cout << "-----------------" << endl;
	cin >> p;
	p.show();
}

注意:在输入输出过程中,cin/cout会记录错误、状态标志,所以不能加const

四、赋值类型运算符重载

成员函数:
void operator=(const A& b)
{
    return(a参数#b参数);
}

注意赋值运算符的调用

A a = val;	//调用单参构造
a = b;		//调用赋值运算符

注意:一般不需要重写赋值运算符,类中有缺省的赋值运算符,当需要深拷贝时才需要显示实现。

五、单目运算符重载

成员函数:
[const] A operator#(void)[const]
{

}
全局函数:
[const] A operator#([const] A& that)
{

}

前–/++

成员函数:
A& operator++(void)
{
	x++,y++;
	return *this;
}
全局函数:
A& operator--(A& that)
{
    p.x--,p.y--;
	return p;
}

后–/++

成员函数:
A operator--(int)
{
    return Point(x--,y--);
}
全局函数:
A operator++(A& that,int)
{
    return Point(p.x++,p.y++);
}

注意:前自变和后自变的参数基本一样,唯一的区别是哑元

六、特殊运算符的重载

[]	//下标运算符,重载了它类对象就可以伪装成数组使用,STL模板库中大多数容器都重载了它。
()	//函数操作运算符,重载了它类对象可以伪装成函数使用。
*	//解引用运算符,
->	//成员访问运算符,重载了它对象可以伪装成指针使用,STL中的智能指针就是通过重载它们实现的。
new/delete	//堆内存管理运算符
    1、C++默认的堆内存管理器速度比较慢,重载new/delete底层就可以使用malloc/free提高运行速度。
    2、当申请内存比较小时,可能会产生内存碎片,重载new之后可以扩大小字节块的内存,减小内存碎片产生的几率。
    3、重载new/delete可以在重载函数中记录内存的使用信息,帮助解决内存泄露的问题。
void* operator new(size_t len)
{
	void* ptr = malloc(len);
	cout << "new:" << ptr << endl;
	return ptr;
}

void operator delete(void* ptr)
{
	free(ptr);
	cout << "delete:" << ptr << endl;
}

七、重载操作符的限制

1、只能重载为成员函数的运算符

​ = [] () -> *

2、只能重载为全局函数的运算符

​ << >>

3、不能重载的运算符

​ :: 域限定符

​ . 直接成员访问符

​ ?: 三目运算符

​ sizeof 字符长度运算符

​ typeid 类型信息运算符

4、重载运算符无法改变运算符的优先级

5、无法重载基本运算符的运算符

6、不能改变运算符的参数个数

7、无法发明新的运算符

八、运算符重载的建议

1、重载运算符时,要根据运算符的实际功能和意义来确定具体的参数、返回值是否需要const属性,返回值是否引用或临时对象。

2、重载运算符要符合情理,要以实际用途为前提。

3、重载运算符是为了让对象的操作更简单、方便,提高代码的可读性,而不是为了炫技。

4、重载运算符时,要与运算符默认的功能以及运算规则一致,不要有反人类的操作。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值