请问C++函数的返回类型(引用和非引用)的区别??

最近在看C++ primer第七章的类Sales_data类中有那么三个函数,返回类型都是&引用类型的,这是什么意思呢?如果不是引用类型的会怎么样?
对于combine的引用,我个人的猜想是因为要返回解引用的*this指针,所以函数返回类型是引用类型,不知道我的猜想对不对?
至于另外两个,书上说IO库不支持拷贝,所以要用引用,这个有点深奥


Sales_data& Sales_data::combine(const Sales_data& rhs)
{
    units_sold += rhs.units_sold;
    revenue += rhs.revenue;
    return *this;
}
istream& read(istream& is, Sales_data& item)
{
    double price = 0;
    is >> item.bookNo >> item.units_sold >> price;
    item.revenue = item.units_sold * price;
    return is;
}
ostream& print(ostream& os, const Sales_data& item)
{
    os << item.isbn() << " " << item.units_sold << " " << item.revenue << " " << item.avg_price();
    return os;
}

值类型是类时,在传递参数、函数返回时,会发生一次额外的拷贝构造,而引用则返回类对象的别名。
就拿你的代码举例,Sales_data& Sales_data::combine(const Sales_data& rhs) 函数返回值是引用类型(Sales_data& ),可不可以是值类型?答案是可以的,原来的combine相当于

Sales_data Sales_data::combine(const Sales_data& rhs) // 返回值是值类型,而非引用类型
{
    ...
    Sales_data temp(*this); // 编译器生成一个临时对象:用*this在栈上拷贝构造temp
    return temp;
}

// 调用处
Sales_data a, b;
Sales_data d = a.combine(b);

同样的,在传参的时候,如果是值传递,而不是引用传递,就会有一次额外的拷贝构造调用。而且,新构造的对象并非原来的对象,但是引用传递的对象却是原来的对象。

Sales_data& Sales_data::combine(const Sales_data primary_obj) // 参数是值类型,而非引用类型
{
    Sales_data temp(primary_obj);
    ...
    return *this;
}

IO库不用值传递(拷贝),而是用引用,我想主要是基于上面2点考虑:
1)效率,值传递会多一次对象拷贝构造,这个开销不小,而且并不是必须的;
2)对拷贝构造的对象的修改,并不会对原对象产生任何影响。

看一下iostream的源码就知道,他的拷贝构造函数是delete的,c++11之前他的拷贝构造函数是protected的,因为输入输出一般来说就一份,内部所引用的具体输入输出硬件:键盘,屏幕,网络,文件等等,一般来说一个对象只针对一份,所以允许复制的话,将有两个所有者对其操作,必然容易引起冲突,因此被设计不可拷贝的