返回非引用类型:
函数的返回值用于初始化在调用函数时创建的临时对象(temporary object),如果返回类型不是引用,在调用函数的地方会将函数返回值复制给临时对象。
在求解表达式的时候,如果需要一个地方存储其运算结果,编译器会创建一个没命名的对象,这就是临时对象。C++程序员通常用temporary这个术语来代替temporary object。
用函数返回值初始化临时对象与用实参初始化形参的方法是一样的。
当函数返回非引用类型时,其返回值既可以是局部对象,也可以是求解表达式的结果。
返回引用类型:
当函数返回引用类型时,没有复制返回值,相反,返回的是对象本身。
千万不要返回局部对象的引用!千万不要返回指向局部对象的指针!
当函数执行完毕时,将释放分配给局部对象的存储空间。此时对局部对象的引用就会指向不确定的内存!返回指向局部对象的指针也是一样的,当函数结束时,局部对象被释放,返回的指针就变成了不再存在的对象的悬垂指针。
返回引用时,要求在函数的参数中,包含有以引用方式或指针方式存在的,需要被返回的参数。
如果返回对象,最后多执行一次拷贝构造函数,如果返回引用,直接返回现存对象
#include <iostream>
using namespace std;
class Timer
{
public:
Timer();
Timer(int, int, int);
friend Timer &operator+(Timer&, Timer&);
friend Timer operator-(Timer&, Timer&);
friend ostream& operator<<(ostream &out, Timer &t);
friend istream& operator>>(istream &in, Timer &t);
private:
int hour, minute, second;
};
Timer::Timer()
{
hour = 0;
minute = 0;
second = 0;
}
Timer::Timer(int hour, int minute, int second)
{
this->hour = hour;
this->minute = minute;
this->second = second;
}
Timer & operator+(Timer& a, Timer &b)
{
a.second = a.second + b.second;
a.minute = a.minute + b.minute;
a.hour = a.hour + b.hour;
if (a.second >= 60)
{
a.second = a.second - 60;
a.minute++;
}
if (a.minute >= 60)
{
a.minute = a.minute - 60;
a.hour++;
}
return a;
}
Timer operator-(Timer &a, Timer &b)
{
Timer c;
c.hour = a.hour - b.hour;
c.minute = a.minute - b.minute;
c.second = a.second - b.second;
if (c.second < 0)
{
c.second += 60;
c.minute--;
}
if (c.minute < 0)
{
c.minute += 60;
c.hour--;
}
return c;
}
ostream& operator<<(ostream &out, Timer &t)
{
out << t.hour << ":" << t.minute << ":" << t.second << endl;
return out;
}
istream& operator>>(istream&in, Timer &t)
{
cout << "Input hours and minutes." << endl;
in >> t.hour >> t.minute >> t.second;
return in;
}
int main()
{
Timer t1, t2, t3, t4;
cin >> t1 >> t2;
cout << "t1=" << t1;
cout << "t2=" << t2;
t3 = t1 + t2;
cout << "t3=t1+t2=" << t3;
t4 = t1 - t2;
cout << "t4=t1-t2=" << t4;
return 0;
}
刚开始我将函数声明为:
friend Timer&operator+(Timer&,Timer&);
friend Timer&operator-(Timer&,Timer&);
对于<<,>>的重载声明的和长代码一样。但是这样做之后我发现出现异常。
在Time &operator+(Timer&t1,Timer&t2)里我声明了一个Timer的局部变量,而当函数调用结束后,该指针变成了悬挂指针。
所以,一定谨记不要在返回值为引用的函数中返回局部变量。