🍓问题现象🍓
看到一个重载Complex类时,重载 =
操作符函数 引发的问题,先上代码
#include <iostream>
using namespace std;
class Time
{
public:
Time(){hour = 0; minu = 0; seco = 0;}
Time(int h, int m, int s) : hour(h), minu(m), seco(s){}
void display();
Time &operator++ ();
Time &operator-- ();
Time operator= (Time &c);
private:
int hour;
int minu;
int seco;
};
void Time::display()
{
cout << hour << ":" << minu << ":" << seco << endl;
}
Time &Time::operator++()
{
hour = hour - 1;
return *this;
}
Time &Time::operator--()
{
hour = hour + 1;
return *this;
}
Time Time::operator=(Time& t)
{
this->hour = t.hour;
this->minu = t.minu;
this->seco = t.seco;
return *this;
}
int main()
{
Time t1(1, 2, 3);
Time t2(4, 5, 6);
Time t3;
t3 = (t1.operator=(t2));
// t1.operator=(t2);
// t3 = t1;
#endif
t3.display();
return 0;
}
以上代码编译后会出现下面报错问题
🍓问题原因🍓
这是一个 临时变量传递
引发的问题
临时变量通常在函数参数传递发生类型转换以及函数返回值时被创建
回到问题代码 t3 = (t1.operator=(t2));
,这里括号里的 t1.operator=(t2)
就是调用函数,获取返回值的过程,也就是说这时存在一个临时变量,当把这个临时变量传递给 =
重载函数时,由于函数形参里定义的是 Time&
,而不是常量引用,并且又将这个临时变量身份的返回值当作另一个 =
重载函数的参数(有点俄罗斯套娃了,这种用法出问题概率比较大)就引发了错误
这个错误是C++编译器的一个关于语义的限制。
如果一个参数是以非const引用传入,c++编译器就有理由认为程序员会在函数中修改这个值,并且这个被修改的引用在函数返回后要发挥作用。但如果你把一个临时变量当作非const引用参数传进来,由于临时变量的特殊性,程序员并不能操作临时变量,而且临时变量随时可能被释放掉,所以,一般说来,修改一个临时变量是毫无意义的,据此,c++编译器加入了临时变量不能作为非const引用的这个语义限制
🍓问题解决🍓
- 如果将
t3 = (t1.operator=(t2));
替换成注释掉的两行代码,编译就不会出错 - 亦或者
=
重载函数的形参里改为const Time&
也不会出错
🍓总结🍓
c++中临时变量不能作为非const的引用参数