4

亲爱的朋友们,我担心我是否在 C++ 中错误地使用了引用在以下方法中 GCC 抱怨警告“对局部变量'me'的引用返回”

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' 变量)是否正确\可接受?

4

5 回答 5

13

编号ref仍然是指me在调用结束时将销毁哪个。

您应该返回结果的副本(不以 为前缀&)。

MatrizEsparsa MatrizEsparsa::operator+(const MatrizEsparsa& outra) const {
    return MatrizEsparsa(outra.linhas(),outra.colunas());
}

我还添加了两个const说明符(参数和方法),因为我怀疑outra在这种情况下需要修改调用实例。(我可能是错的,但你operator+会有一个奇怪的语义)

通过做你所做的,你只是让代码更复杂。编译器可能很困惑,无法警告您可能出现的错误。

通常,当你不得不使用巧妙的技巧来做简单的事情时,就意味着出了点问题。

于 2010-07-06T13:30:36.173 回答
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+=.

于 2010-07-06T14:40:21.953 回答
2

不,您必须在此处返回一个值,最好是一个const值。参见有效 C++,第 21 条。

我建议如下界面:

const MatrizEsparsa operator+(const MatrizEsparsa& left, const MatrizEsparsa& right);

请注意,所有内容要么是const引用,要么是const值。返回const值不如返回值或将参数声明为const引用重要,但 Scott Meyers 的论点说服了我,尽管没有人遵循它们。

于 2010-07-06T13:30:26.640 回答
2

这是不可接受的。这其实是同一个问题:返回一个对本地对象的非常量引用,该对象在返回方法后会被销毁。

于 2010-07-06T13:30:31.357 回答
0

您无法返回引用,因为您引用的对象将在您的控制之外被破坏。要么将“我”作为 MatrizEsparsa 的成员变量,以便它在函数执行后持续存在,否则返回指向该对象的指针或 boost smart_ptr。

虽然这是一个 + 运算符,但您可能希望返回一个值而不是对函数内部变量的引用。

于 2010-07-06T15:15:01.480 回答