写这篇博客的起因是今天一直困扰我的问题,本来是练习运算符的重载,在写加法的重载和减法的重载都是没有问题的,但是加上了赋值运算符的重载马上就出现的问题,先摆出我的错误代码:
class Date{
public:
Date(int year = 1000, int month = 1, int day = 1)
{
cout << "Date(int ,int ,int)" << this << endl;
_year = year;
_month = month;
_day = day;
}
Date(const Date& d1)
{
cout << "Date(const Date& d1)" << this<<endl;
_year = d1._year;
_month = d1._month;
_day = d1._day;
}
void SetDate(int year, int month, int day)
{
_year = year;
_month = month;
_day = day;
}
void Print()
{
cout << _year << "-" << _month << "-" << _day << endl;
}
~Date()
{
cout << "~Date()" << endl;
}
Date& operator+(int day)
{
Date temp(*this);
temp._day+= day;
return temp;
}
Date& operator-(int day)
{
Date temp(*this);
temp._day -= day;
return temp;
}
Date& operator=(const Date& d)
{
if (&d != this)
{
_year=d._year;
_month = d._month;
_day = d._day;
}
return *this;
}
private:
int _year;
int _month;
int _day;
};
void TestFunc()
{
Date d1(2018, 7, 30);
Date d2;
d2.Print();
d2 = d2.operator+(5);
d2.Print();
d2 = d2.operator-(2);
d2.Print();
d2=d1;
d2.Print();
}
int main()
{
TestFunc();
system("pause");
return 0;
}
结果为:
当我去掉赋值符号的重载以后,又是 正确结果,如图:
让我苦恼了很久,难道是我的赋值运算符的重载影响到了前面的符号重载,几番思考调试之后,发现是,之前的加法和减法的返回值是有问题的,temp是一个临时变量,出了函数的作用域就会被销毁,返回的应该是值,而不是引用,因为引用共享那一块空间,出了函数后,空间被销毁,再次赋值,那么指向的就是一个随机值。
附上正确代码:
class Date{
public:
Date(int year = 1000, int month = 1, int day = 1)
{
cout << "Date(int ,int ,int)" << this << endl;
_year = year;
_month = month;
_day = day;
}
Date(const Date& d1)
{
cout << "Date(const Date& d1)" << this<<endl;
_year = d1._year;
_month = d1._month;
_day = d1._day;
}
void SetDate(int year, int month, int day)
{
_year = year;
_month = month;
_day = day;
}
void Print()
{
cout << _year << "-" << _month << "-" << _day << endl;
}
~Date()
{
cout << "~Date()" << endl;
}
Date operator+(int day)
{
Date temp(*this);
temp._day+= day;
return temp;
}
Date operator-(int day)
{
Date temp(*this);
temp._day -= day;
return temp;
}
Date& operator=(const Date& d)
{
if (&d != this)
{
_year=d._year;
_month = d._month;
_day = d._day;
}
return *this;
}
bool operator<(const Date& d)//<的重载
{
if (_year < d._year || (_year == d._year&&_month < d._month) || (_year == d._year&&_month == d._month&&_day == d._day))
return true;
else
return false;
}
bool operator==(const Date& d)//==的重载
{
if (_year == d._year&&_month == d._month&&_day == d._day)
return true;
else
return false;
}
bool operator!=(const Date& d)
{
return !(*this == d);
}
//前置++:先++,再赋值
Date& operator++()
{
_day += 1;
return *this;//生命周期比函数长,所以可以返回引用
}
//后置++,先赋值,再加加
Date operator++(int)
{
Date temp(*this);//调用了一个拷贝构造函数
_day += 1;
return temp;//返回值是临时变量,只能传值返回
}
private:
int _year;
int _month;
int _day;
};
void TestFunc()
{
Date d1(2018, 7, 30);
Date d2;
d2.Print();
d2 = d2.operator+(5);
d2.Print();
d2 = d2.operator-(2);
d2.Print();
d2=d1;
d2.Print();
Date d3(2018, 2, 19);
Date d4(2018, 3, 10);
if (d3 < d4)
cout << "2.19<3.10" << endl;
else
cout << "error" << endl;
if (d3 == d4)
cout << "d3==d4" << endl;
else
cout << "2.19!=3.10" << endl;
}
int main()
{
TestFunc();
system("pause");
return 0;
}
结果为:
注意:赋值运算符的重载如果返回值是一个临时变量,那么返回值就不能是引用类型,当返回值不是临时变量,即返回值的生命周期长于函数时,那么返回值就可以是引用类型,返回值最好是引用类型,否则会造成内存的浪费。