【C++】返回值是类名和返回值是引用的区别

返回非引用类型:

函数的返回值用于初始化在调用函数时创建的临时对象(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的局部变量,而当函数调用结束后,该指针变成了悬挂指针。
所以,一定谨记不要在返回值为引用的函数中返回局部变量。

猜你喜欢

转载自blog.csdn.net/siyue0211/article/details/76906981