【C++基础】常量引用作形参解决递增运算符重载的问题

上回发的帖子里讲了为什么要用常引用作形参【C++基础】常量引用、指针常量与常量指针 ; 顶层const与底层const
今天又遇到常量引用作形参的一个例子,在学习黑马视频的重载++运算符时,有一个错误。它的重载左移运算符<<的第二个形参为普通引用MyInteger& p

ostream& operator<<(ostream &cout, MyInteger& p)
{
	cout << p.m_Num << endl;
	return cout;
}

而重载后置++运算符的函数,因为返回值是变量,如下

MyInteger operator++(int)
	{
		MyInteger temp = *this;
		m_Num++;
		return temp;
	}

导致调用函数时

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

因为myint++是调用后置operator++函数的返回值,该函数返回的是变量值,不是引用,而左移运算符<<重载函数的第二形参是引用类型,所以这里的<<会报错!

当然,可以把<<函数的第二个形参改为MyInteger p,这样就不会报错,但是前置++重载调用那块报错,因为前置++重载函数返回的是引用类型:

MyInteger& operator++()
	{
		//先进行++运算
		m_Num++;
		//再返回自身
		return *this;
	}

如下,++(++myint)是引用类型,他作为左移运算符<<重载函数的实参与MyInteger p 类型不匹配,应为MyInteger& p

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

那这样就陷入矛盾,只能取其一吗,其实不然。我们可以把第二个形参设置为常量引用,即const MyInteger& p

ostream& operator<<(ostream &cout, const MyInteger& p)
{
	cout << p.m_Num << endl;
	return cout;
}

上篇帖子写过,const int&可以绑定到普通int上,所以我们把普通常量作为实参,传入常量引用作为形参的函数,也不会出错,这就是上篇帖子说的

非常量 可以转成 常量

由此可见,常量引用作为形参,比普通引用作形参,能接受更多的实参类型,上篇帖子的“hello world”也是一个例子。

完整代码如下

#include
using namespace std;


class MyInteger
{
	friend ostream& operator<<(ostream &cout, const MyInteger& p);
public:
	MyInteger()
	{
		m_Num = 0;
	}
	//重载前置++运算符,  返回引用是为了一直对一个数据进行递增操作
	MyInteger& operator++()
	{
		//先进行++运算
		m_Num++;
		//再返回自身
		return *this;
	}

	//重载后置++运算符
	//int代表占位参数,可以区分前置和后置递增,没有int会认为是重载上面的函数,而仅仅返回值不同又不能重载
	MyInteger operator++(int)
	{
		//后置递增,先做表达式运算再让变量自加1
		//先 记录当时结果
		MyInteger temp = *this;
		//后 递增
		m_Num++;
		//最后将记录的结果做返回操作
		return temp;
	}
	//后置递增是返回值,前置是返回引用。因为后置递增里temp是局部变量,函数调用完就销毁掉了,后面再引用就是非法操作
private:
	int m_Num;
};
//第二个形参改成常量引用
ostream& operator<<(ostream &cout, const MyInteger& p)
{
	cout << p.m_Num << endl;
	return cout;
}

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

void test02()
{
	MyInteger myint;
	cout << myint++ << endl;
	cout << myint << endl;
}
int main()
{
	test01();
	test02();
	return 0;
}

你可能感兴趣的:(C++学习笔记,c++,面试)