C++类与对象笔记十二:运算符重载三:递增运算符重载

先看看系统自带的递增运算符++

 // 递增运算符重载 ++; a++; ++a
 int a = 10;
 cout << ++a << endl;  // 11  先加,后输出。
 cout << a << endl;    // 11  已加。

 int b = 10;
 cout << b++ << endl;  // 10  先输出,然后再加。
 cout << b << endl;    // 11  已加。

我们定义我们自己的整型。满足前置递增,后置递增。

class MyInt
{
public:
	MyInt()
	{
		m_Num = 0;
	}
private:
	int m_Num;
};

调用一下试试:

 左移运算符报错,说没有匹配的类型。所以我们需要重载,包括使用++也会报错。

 所以自己的类型,必须重新定义个运算符重载。

为了使得我们的cout在左侧,所以只能定义一个全局的重载运算符函数。

ostream& operator<<(ostream& cout, MyInt myint)
{
	cout << myint.m_Num;
    return cout;
}

同时在类内将全局函数声明为友元

friend ostream& operator<<(ostream& cout, MyInt myint);

此时:调用时,左移不再报错。可以cout输出,至于++仍需要重载。 




 递增运算符++有两种:前置,后置;

1、前置递增++运算符

MyInt& operator++()
{
	m_Num++;  // 前置:先加,后返回。
	return *this;
}

前置递增:先加,然后返回,返回的是本体的值。所以要接收本体值。解引用this,同时返回值具有链式,所以,是返回本体值的引用。因此:return *this;返回的是调用者本身:MyInt&。 

this是指向自身的,把自身解引用。返回的是本身:因此返回值类型也是MyInt类型的引用

问题:为何返回本身之后,还要返回引用:返回MyInt类型的值可以吗?

答:返回值满足前置需求,但是因为链式。如果不加,重载函数返回的是:一个新的对象,这个对象不是原来的对象,因此链式加一,并没有加到原来的值上。

返回引用是为了一直对一个数据对象操作加一。

查看调用情况:

成功了。 我们再看后置递增。

2、后置递增++运算符

我们现在类内,尝试写个架子(框架:不知道返回值先写一个void,函数名知道operator++(){}):

 报错:无法重载仅按返回类型区分的函数。返回类型不是函数签名,不是区分函数重载的条件。

重载的条件:

  • 同一作用域下。
  • 函数名相同。
  • 参数不同:类型个数顺序。不同即可。

那么在C++中,这种情况咋办呢?在参数列表中加上一个(int)

加上一个int之后,可以认为:这是一个++运算符的重载。

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

这个int代表的是一个占位参数,可以用于区分:前置和后置。 写上之后,编译器自己就能区分了,这是一个占位符,表示这边需要输入一个int类型。参数类型不同的重载。

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

而且这个地方必须写int,写double和float都不好使。

比如我们想写一个我们自己的类型。MyInt。不行。

 区分前置和后置:用占位参数:int。记住。

继续往下走,后置递增:先返回本体;然后再++。

但是有个问题:返回return之后的代码都将无效。

因此需要有个变量temp先临时记忆一下当前的值,存储这个返回值,然后让这个值加一后,最后再把临时记录存储值的变量temp返回。

// 重载后置递增。
MyInt operator++(int)  // int 代表占位参数。占位参 数可以区分前置和后置递增。
{
	MyInt temp = *this;
	m_Num++;
	return temp;
}

此处要非常注意我们返回的是值,而不是引用了。

因为,如果我们如果返回的是引用,相当于返回的是临时的局部变量temp。这个局部变量temp保存在栈中,在当前函数执行完之后,就立即销毁了,内存释放,后面如果还要返回,还要继续调用,那么就是非法操作。所以后置递增一定要返回值。

前置递增返回的是引用;后置递增返回的是




递增运算符重载全部代码:

#include<iostream>
using namespace std;

class MyInt
{
	friend ostream& operator<<(ostream& cout, MyInt myint);
public:
	MyInt()
	{
		m_Num = 0;
	}
	// 递增有两种:前置递增和后置递增。同时具有链式。
	// 重载前置递增。
	MyInt& operator++()
	{
		m_Num++;  // 前置:先加,后返回。
		return *this;
	}

	// 重载后置递增。
	MyInt operator++(int)  // int 代表占位参数。占位参 数可以区分前置和后置递增。
	{
		MyInt temp = *this;
		m_Num++;
		return temp;
	}

private:
	int m_Num;
};

ostream& operator<<(ostream& cout, MyInt myint)
{
	cout << myint.m_Num;
	return cout;
}

void test01()
{
	MyInt myint;
	cout << myint << endl;
	myint++;
}
void test02()
{
	MyInt myint;
	cout << myint++ << endl;
	cout << myint << endl;
}

//虽是一元,但是链式编程。
 int main()
 {
	 // 递增运算符重载 ++; a++; ++a
	 int a = 10;
	 cout << ++a << endl;  // 11  先加,后输出。
	 cout << a << endl;    // 11  已加。

	 int b = 10;
	 cout << b++ << endl;  // 10  先输出,然后再加。
	 cout << b << endl;    // 11  已加。

	 int c = 10;
	 cout << ++++c << endl;
	 cout << c << endl;

	 test02();

	 system("pause");
	 return 0;
 }

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值