亲爱的朋友们,我很担心我是否在C ++中使用了很多引用 在下面的方法中,GCC抱怨警告“引用本地变量'我'返回”
MatrizEsparsa& MatrizEsparsa::operator+(MatrizEsparsa& outra){
MatrizEsparsa me(outra.linhas(),outra.colunas());
return me;
}
但是,通过以下更改,警告消失:
MatrizEsparsa& MatrizEsparsa::operator+(MatrizEsparsa& outra){
MatrizEsparsa me(outra.linhas(),outra.colunas());
MatrizEsparsa &ref = me;
return ref;
}
前一种方法(返回'ref'变量)是否正确\可接受?
答案 0 :(得分:13)
没有。 ref
仍然引用me
,它将在通话结束时销毁。
您应该返回结果的副本(不以&
为前缀)。
MatrizEsparsa MatrizEsparsa::operator+(const MatrizEsparsa& outra) const {
return MatrizEsparsa(outra.linhas(),outra.colunas());
}
我还添加了两个const
说明符(对参数和方法),因为我怀疑outra
或者在这种情况下需要修改调用实例。 (我可能错了,但是你的operator+
会有一个奇怪的语义)
通过做你所做的,你只是使代码更复杂。编译器可能很困惑,无法警告你可能的错误。
通常,当你必须使用巧妙的技巧来做简单的事情时,这意味着出了问题。
答案 1 :(得分:4)
我认为你误解了你的经营者。
有2:
struct Foo
{
Foo& operator+=(Foo const&);
Foo operator+(Foo const&) const;
};
正如您所注意到的,第一个返回对自身的引用,第二个不返回。
另外,一般来说,第二个应该写成自由函数。
Foo operator+(Foo const&, Foo const&);
这可以自动化,因为它很麻烦,使用Boost.Operators:
struct Foo: boost::addable<Foo>
{
Foo& operator+=(Foo const& rhs)
{
// add
return *this;
}
};
小boost::addable
魔法将根据+
自动生成Foo::operator+=
实施。
答案 2 :(得分:2)
不,您必须在此处返回一个值,理想情况下为const
值。参见Effective C ++,第21项。
我建议使用以下界面:
const MatrizEsparsa operator+(const MatrizEsparsa& left, const MatrizEsparsa& right);
请注意,所有内容都是const
引用或const
值。返回const
值并不像返回值或将参数声明为const
引用那么重要,但Scott Meyers的论据让我信服,尽管没有人遵循它们。
答案 3 :(得分:2)
这是不可接受的。它实际上是同样的问题:将一个非const引用返回给一个在返回方法后将被销毁的本地对象。
答案 4 :(得分:0)
您无法返回引用,因为您引用的对象将在您的控件之外被销毁。将“me”作为MatrizEsparsa的成员变量放置,以便在执行函数后它将保持不变,否则返回指向对象的指针或boost smart_ptr。
虽然看到这是一个+运算符,但您可能希望返回一个值而不是对函数内部变量的引用。