从对象初始化程序返回对本地变量“...”的引用

4
我将尝试重载运算符以将PPM图像相加,从而创建一个新的图像。然而,在尝试在函数中创建新对象时,遇到了问题。
PPM& PPM::operator*(const double& rhs) const {
     int height = this->getHeight();
     int width = this-> getWidth();
     int mc = this-> getMaxColorValue();
     PPM lhs;
     // ...
     return lhs;
}

还有很多其他的内容,最后一行是return(lhs); 当我尝试编译代码时,会出现一个错误,提示:

error: reference to local variable 'lhs' returned [-Werror=return-local-addr] PPM lhs;

出了什么问题?


1
你选择将返回类型定义为 PPM& 而不是 PPM,有什么原因吗? - walnut
2
返回对 lhs 的引用将导致悬空引用,因为它超出了作用域。 - UnholySheep
2
错误描述了出现了什么问题:您在函数内部创建了一个名为lhs的临时变量。当您返回对lhs的引用时,初始对象将被删除,因此引用将是垃圾,编译器会警告您。您需要通过值返回。 - Alex Huszagh
我在课堂上得到了这个任务,并被告知返回类型需要是 PPM& - Fading3clipse
3
对于 operator* 来说,这种情况非常不寻常。operator*= 通常返回一个引用,但是 operator* 通常会返回一个值。我不知道在这里返回引用会有什么意义。 - walnut
@Fading3clipse嗯,那你可能想在对象的构造函数中预计算lhs的值,这样你就可以返回一个类变量的引用。然而,这仍然是非常不寻常的,因为你不应该对operator*进行按引用返回。 - Alex Huszagh
2个回答

4

PPM lhs; 是局部变量,不能返回对局部变量的引用。函数结束时,lhs 将会被销毁,如果你编译通过,你将进入未定义的行为状态。


1
我该如何返回对象的实际值或对象本身? - Fading3clipse
2
@Fading3clipse 如果你想要返回值,只需要从函数返回类型中删除 & 符号即可。 - Oblivion
3
那个方法起作用了,现在回头看作业,我发现我不小心在返回值中添加了 & 符号,所以谢谢你! - Fading3clipse

0

你的operator*是一个成员函数。当像这样调用时:

some_ppm * 1.2

这里,1.2 是你的 double rhs

但是你的 lhs 是什么呢?

看一下你的函数,左边不是 some_ppm。看一下:

PPM& PPM::operator*(const double& rhs) const {
     // ...
     PPM lhs;
     // ...
     return lhs;
}

在这种情况下,lhs总是一个本地的PPM新实例
那么真正的rhs在哪里?
请记住,当你调用一个重载运算符时,实际上是调用了成员函数:
some_ppm.operator*(1.2) // actually well formed syntax

没错,你猜对了,它就是this。而你的运算符不应该返回PPM的引用,而应该像doubleint或者甚至是std::string一样返回一个副本

//v----- return by value
PPM PPM::operator*(const double& rhs) const {
    int height = this->getHeight();
    int width = this-> getWidth();
    int mc = this-> getMaxColorValue();
    PPM result;

    // ...

    return result;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接