C++(3)——运算符重载

运算符重载

运算符的重载实际是一种特殊的函数重载,必须定义一个函数,并告诉C++编译器,当遇到该重载的运算符时调用此函数。这个函数叫做运算符重载函数,通常为类的成员函数。
定义运算符重载函数的一般格式:

返回值类型 类名::operator重载的运算符(参数表)
	{……}

operator是关键字,它与重载的运算符一起构成函数名。
今天对于该问题的学习,我们以下面的类为例:

class Int
{
	private:
		int value;
	public:
		Int(int x = 0):valie(x){}
		Int(const Int &it):value(it.value){}
		~Int(){}
}

我们先来写一个加法函数:Add

int main()
{
	Int a(10),b(10);
	Int c;
	c = a.Add(b); //c.value = a.value + b.value;
	// c = Add(&a,b);
}

第一种:这种写法创建了3个对象,x(copy时),tmp,临时对象(返回给c)

Int Add(Int x)
//Int Add(Int * const this ,Int x)
{
	int val = this->value + x.value;
	Int tmp(val);
	return tmp;
}

第二种:添加引用,只创建了一个临时对象

Int Add(Int &x)
//Int Add(Int * const this ,Int &x)
{
	int val = this->value + x.value;
	return Int(val);
}

第三种:修改了x或this对象的属性值,为了避免这种错误,我们常常将此类方法写为常方法

Int Add(Int &x)
//Int Add(Int * const this ,Int &x)
{
	x.value += this->value;//改了x
	//this->value += x.value;//改了this(b)
	return Int(x.value);
}
Int Add(Int * const this ,Int &x)

这里的const约束的是this自身,写在函数的后面

Int Add( const Int &x) const
//Int Add( const Int * const this ,Int &x)

这里的const约束的是this的指向

改法如下:

Int Add( const Int &x) const
{
	int val = this->value + x.value;
	return Int(val);
}

函数名Add被改为+号是不被允许的,因此我们需要如下的运算符重载函数:

Int operator+(const Int &x) const
//Int operator+(const Int * const this, const Int &x) const
{
	int val = this->value + x.value;
	return Int(val);
}
//c = a+ b;
//c = a.operator+(b);
//c = operator+(&a,b); 

减法,乘法很好改写,只有除法需要处理一下:

Int operator/( const Int &x) const
{
	if(x.value == 0)exit(EXIT_FAILURE);
	int val = this->value / x.value;
	return Int(val);
}

下面进一步完善Add函数,将“对象+对象”扩展到“对象+ 变量”和“变量 + 对象”

1.对象+变量

Int operator+(const int x) const
{
	int val = this->value + x;
	return Int(val);
	//return *this + Int(x);
	//Int(x)将构建一个对象
	//这一句可以将其转化为对象+对象,只是Int(x)没有姓名,调试到此处会转调对象+对象
}

思考:对于内置类型x是否需要添加引用?

答:不需要,因为加了引用后,从引用的本质上来看,反而增加了对内存的访问次数。

2.变量+对象

我们常会写成这样:

Int operator+(const int x , const Int &it) 

但由于参数过多,编译不会通过,运算符重载函数不允许参数过多,这里有三个参数。
因此不能将这个函数设置成类的成员函数,而需要将其设计成全局函数
当改为全局函数时,就没了this指针。

Int operator+(const int x,const Int &it) 
{
	return it + x;
	//变量+对象——》对象+变量-》对象+对象
}

赋值函数:

void operator=(const Int &it)
{
	this->value = it.value;
}

我们可以从函数的本质上看出这个函数不能完成连续赋值,
改写为:

Int & operator=(const Int &it) //以引用返回就不构建临时对象了,而值返回将会构建一个临时对象
{
	if(this != &it)//c = c这种情况需要特殊处理这里的&不是引用,是取地址符
	{
		this->value = it.value;
	}
	return *this;//*this代表主函数中的一个对象,不受该函数的影响,因此可以以引用返回

	//c = a = b;
	//c.operator=(a.operator=(b));
	//operator=(&c,operator=(&a,b));
	*/
}

C++中禁止重载4个的运算符:

在这里插入图片描述

在C++中调用C语言的函数

extern "C"表示编译生成的内部符号名使用C约定。C++支持函数重载,而C不支持,两者的编译规则也不一样。函数被C++编译后在符号库中的名字与C语言的不同。

例如,假设某个函数的原型为:void foo( int x, int y ); 该函数被C编译器编译后在符号库中的名字可能为_foo,而C++编译器则会产生像_foo_int_int之类的名字(不同的编译器可能生成的名字不同,但是都采用了相同的机制,生成的新名字称为“mangled name”)。_foo_int_int这样的名字包含了函数名、函数参数数量及类型信息,C++就是靠这种机制来实现函数重载的。下面以例子说明,如何在C++中使用C的函数,或者在C中使用C++的函数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值