请问effective c++里面两个函数的区别

请教effective c++里面两个函数的区别
const   Rational&   operator*   (const   Ratinal&   lhs,cibst   Ratuibak&   rhs)
{  
        Ratinal   result(lhs.n*rhs.n,   lhs.d*rhs.d);
        return   result;
}

inline   const   Rational   operator*   (const   Ratinal&   lhs,cibst   Ratuibak&   rhs)
{  
        return   Ratinal(lhs.n*rhs.n,   lhs.d*rhs.d);
}

第一个函数的result是个local对象,在函数退出之前被销毁了,第二个中的对象是在栈上创建的吗?作用范围是什么,谢谢

------解决方案--------------------
第一个函数:

const Rational& operator* (const Ratinal& lhs,cibst Ratuibak& rhs)
{
Ratinal result(lhs.n*rhs.n, lhs.d*rhs.d);//构造一个局部对象!
return result;
}

上述函数内部构造了一个局部对象,返回值将以常型引用指向之!因此,这函数表达了一个错误的语意,以引用去指向不存在的东西!

在我的VC7.1编译器上会生成一个警告错误: "warning C4172: 返回局部变量或临时变量的地址! "
在我的Gcc编译器上也会生成一个警告错误:
warning: reference to local variable `_f ' returned
针对上述两个编译器,该函数可以通过编译链接执行!

在BC6.0编译器产生编译错误:
[C++ Error].cpp(30): E2363 Attempting to return a reference to local variable '_f '
该函数无法通过编译!

在VC及Gcc上从调试器中观察该函数中的局部对象在该函数结束时已经析构,且没有临时对象的产生,此时使用该函数的返回值(const Rational& )去寻址期望的对象有不可预见的结果!

请参考如下程序:

class Fish
{
long x;
public:
Fish(const long& _x = 0) : x(_x)
{
cout < < "建构Fish " < < endl;
}

~Fish()
{
cout < < "析构Fish " < < endl;
}
void show(void)const
{
cout < < "成员x: " < < x < < endl;
}
};

const Fish& Testf()
{
Fish _f(8);//以 '8 '初始化建构局部对象变量;

//期望如下语句返回成员x值是8的局部对象_f:

return _f;//生成错误warning C4172: 返回局部变量或临时变量的地址

//_f在此被析构!
}

int main()
{
const Fish& _fx = Testf();//_fx期望的常型引用返回值!
_fx.show(); //期望输出 "成员x:8 ",实际输出x值为不可预见值!

_PAUSE;
return 0;
}

综上所述,上述函数表达了一个错误的语意,以引用去指向不存在的东西(空引用,这是违反语言规则的!),这应是编译器的bug吧(而且指向的的确是个无用的东东)!

第二个函数:

inline const Rational operator* (const Ratinal& lhs,cibst Ratuibak& rhs)
{
return Ratinal(lhs.n*rhs.n, lhs.d*rhs.d);
}

这函数与第一个相比有明显不同,如我们都看见的有内联声明(让编译器去看吧!),这个函数构造一个匿名对象,并以此作为返回值。

它代表了一个的正确C++语意之一:返回一个值对象!各种编译器均能对此有良好的支持!

请参考如下程序:

class Fish
{
long x;
public:
Fish(const long& _x = 0) : x(_x)
{
cout < < "建构Fish " < < endl;
}

Fish(const Fish& _f)
{
x = _f.x;
cout < < "考贝建构Fish " < < endl;
}
~Fish()
{
cout < < "析构Fish " < < endl;
}
void show(void)const
{
cout < < "成员x: " < < x < < endl;
}
};

const Fish Testf()
{
Fish _f(8);//
return _f;//这儿将以_f为初值考贝建构一个Fish临时对象!
}

int main()
{
const Fish& _f = Testf();
_f.show();

_PAUSE;
return 0;
}

所以第二个函数:

inline const Rational operator* (const Ratinal& lhs,cibst Ratuibak& rhs)
{
return Ratinal(lhs.n*rhs.n, lhs.d*rhs.d);
}

有语意正确,编译器行为良好的优点!

关于其中提到的临时对象,我刚在论坛上参加了讨论,现针对上述程序摘略如下:

Testf()是返回一个临时对象,并且以引用绑定这个临时对象,这样一来,根据C++标准对临时对象生命期的规定二,Testf()产生的那个临时对象必须要等绑定它的引用_f的生命期结束,它才可以被析构!