上回发的帖子里讲了为什么要用常引用作形参【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”也是一个例子。
完整代码如下
#includeusing 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; }



