我们发现,在C++中,有些成员函数返回的是对象,而有些函数返回的又是引用。
返回对象和返回引用的最主要的区别就是函数原型和函数头。
Car run(const Car &) //返回对象
Car & run(const Car &) //返回引用
返回对象会涉及到生成返回对象的副本,这事调用函数的程序可以使用的副本,因此,返回对象的时间成本包括了调用复制构造函数来生成副本所需的时间和调用析构函数删除副本所需的时间。返回引用可以节省时间和内存。直接返回对象与按值传递对象类似,他们都生成临时副本。同样,返回引用与按引用传递对象类似,调用和被调用的函数对同一个对象进行操作。
并不是总是可以返回引用的,当函数不能返回在函数中创建的临时对象的引用,因为当函数结束时,临时对象将消失,因此这种引用是非法的,在这种情况下,应返回对象,以生成一个调用程序可以使用的副本。
如:
RMB& RMB::operator++()
{
yuan++;
return *this;
}
RMB RMB::operator++(int)
{
RMB temp(yuan); //创建对象
yuan++;
return temp; //返回对象的副本
}
通用的规则是,如果函数返回在函数中创建的临时对象,则不要使用引用,如果先创建一个对象,然后返回改对象的副本,则可以使用返回对象,如上述第二种情况。
如果函数返回的是通过引用或指针传递给它的对象,则应当按引用返回对象。当按引用返回调用函数的对象或作为参数传递给函数的对象。如上面的第一种情况。
C++笔记--返回对象还是返回引用
扩展例子-计算有理数的四则运算
#include <iostream>
#include <cstdlib>
using namespace std;
int gongyueshu(int a,int b) /*欧几里得辗转相除法*/
{
int ret;
if(a!=b)
{
int m, n;
m = (a>b)?a:b;
n = (a>b)?b:a;
while(n)
{
ret = m%n;
m = n;
n = ret;
}
ret = m;
}
else
{
ret = a;
}
return ret;
}
class Rational
{
private:
int numerator;
int denominator;
public:
Rational()
{
numerator = 0;
denominator = 1;
cout << "Rational()" << endl;
}
Rational(int numerator, int denominator)
{
if(denominator<0) /*防止负号出现在分母上*/
{
numerator = -numerator;
denominator = -denominator;
}
this->numerator = numerator;
if(denominator!=0)
this->denominator = denominator;
cout << "Rational()" << endl;
/*throw exception*/ /*分母为0抛异常待补充*/
}
Rational(const Rational& obj)
{
numerator = obj.numerator;
denominator = obj.denominator;
cout << "Rational(const Rational& obj)" << endl;
}
Rational& operator +(Rational& obj)
{
numerator = numerator*obj.denominator + denominator*obj.numerator;
denominator *= obj.denominator;
return *this;
}
Rational& operator -(Rational& obj)
{
numerator = numerator*obj.denominator - denominator*obj.numerator;
denominator *= obj.denominator;
return *this;
}
Rational operator *(Rational& obj) /*返回对象会调用拷贝构造和析构函数*/
{
numerator *= obj.numerator;
denominator *= obj.denominator;
return *this;
}
Rational operator /(Rational& obj)
{
numerator *= obj.denominator;
denominator *= obj.numerator;
return *this;
}
void print()
{
int temp = gongyueshu(abs(numerator),abs(denominator));
numerator /= temp;
denominator /= temp;
if(denominator!=1)
{
cout << numerator << "/" << denominator << endl;
}
else
{
cout << numerator << endl;
}
}
~Rational()
{
cout << "~Rational()" << endl;
}
};
int main()
{
/* int m, n;
cin >> m;
cin >> n;
cout << gongyueshu(m,n) << endl;
*/
Rational a1(-1,-8);
Rational a2(7,8);
a1 = a1+a2;
a1.print();
a1 = a1-a2;
a1.print();
a1 = a1*a2;
a1.print();
a1 = a1/a2;
a1.print();
return 0;
}