2010-07-06 75 views
4

亲爱的朋友们,我很担心,如果我做不好的使用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; 
} 

是前一种方法(返回“裁判”变量)正确\接受吗?

+0

对我来说都不好看 – 2010-07-06 13:30:20

+1

@Chris Card:可能是'MatrizEsparsa&'。 @Lucas:'operator +'通常应该是一个独立的函数来允许隐式类型转换。请参阅有效的C++,第24项。 – Philipp 2010-07-06 13:32:50

+1

对问题+1,因为学习如何隐藏编译器的错误总是很有趣:D – ereOn 2010-07-06 13:39:45

回答

13

ref仍指me,在通话结束时将被销毁。

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

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

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

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

通常,当你不得不使用巧妙的技巧来做简单的事情时,这意味着有些事情是错误的。

2

不,您必须在此处返回一个值,理想情况下为const值。见收效C++,第21项

,我建议如下界面:

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

注意,一切要么是const引用或const值。返回const值并不像返回一个值或声明参数为const引用那么重要,但Scott Meyers的论点让我确信,尽管没有人遵循它们。

+0

结果的不变性是另一场辩论。返回一个const引用会顺便说一句,仍然是不正确的。 – ereOn 2010-07-06 13:32:40

+0

我会购买并阅读Effective C++,谢谢! – Lucas 2010-07-06 13:44:09

+0

@ereOn:是的,Effective C++中的建议解决方案是一个常量值。 const引用是(或者至少在C++ 0x之前)通常用作函数的返回类型,例如不需要创建新对象的'std :: min'。 – Philipp 2010-07-06 13:58:43

2

这是不可接受的。它实际上是同样的问题:返回一个非const引用到一个本地对象,该对象将在返回该方法后被销毁。

+5

为什么强调非const?返回一个const引用将会有问题... – fredoverflow 2010-07-06 13:44:25

+0

我想知道:在标准中没有什么东西要求如果必要的话,绑定到const引用的对象的生命周期被扩展,以便const引用是有效的? 'Foo const&result = foo1 + foo2'是有效的,即使典型的'+'运算符返回一个副本,但我不知道它是否适用于返回... – 2010-07-06 17:23:31

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+=+实施。

+0

+1:对于很好的boost ::可添加的技巧。 – ereOn 2010-07-07 05:58:33

0

您不能返回引用,因为您引用的对象将在您的控件之外被销毁。或者把“我”作为MatrizEsparsa的成员变量,以便它在执行该函数后保持不变,否则返回一个指向该对象的指针或提升smart_ptr。

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