【发布时间】:2014-03-07 15:29:56
【问题描述】:
我的问题是:返回对通过引用传递的输入变量的引用是否合法。 我借用C++: Life span of temporary arguments?和return by rvalue reference的例子
#include <iostream>
#include <string>
class MatrixClass
{
public:
int m_value;
std::string m_str;
MatrixClass(int a)
{
m_value = a;
std::cout << "hello: " << m_value << '\n';
}
MatrixClass(const MatrixClass& A)
{
m_value = A.m_value;
std::cout << "hello: " << m_value << '\n';
if (A.m_str == "temp_in_*")
{
std::cout << "string: " << "copied from temp_in_*" << '\n';
}
}
void operator=(const MatrixClass& A)
{
m_value = A.m_value;
std::cout << "hello: " << m_value << '\n';
if (A.m_str == "temp_in_*")
{
std::cout << "string: " << "copied from temp_in_*" << '\n';
}
}
~MatrixClass()
{
std::cout << "bye: " << m_value << '\n';
if (m_str == "temp_in_*")
{
std::cout << "string: " << "temp_in_*" << '\n';
}
}
};
MatrixClass& operator+(MatrixClass& tempClassA, MatrixClass& tempClassB)
{
tempClassA.m_value += tempClassB.m_value;
return tempClassA;
}
MatrixClass operator*(MatrixClass& tempClassA, MatrixClass& tempClassB)
{
MatrixClass Temp(101010);
Temp.m_value = tempClassA.m_value * tempClassB.m_value;
Temp.m_str = "temp_in_*";
return Temp;
}
int main()
{
MatrixClass A1(2);
MatrixClass A2(3);
MatrixClass A3(10);
MatrixClass A4(11);
MatrixClass A5(12);
std::cout << "start of expression " << '\n';
MatrixClass A6(0);
A6 = A1 * A2 + A3 * A4 + A5 * A6;
std::cout << "end of expression " << '\n';
std::cout << "A6.m_value: " << A6.m_value << '\n';
std::system("pause");
}
运算符返回对其输入的引用,该引用是一个临时变量,并通过 它给另一个运算符: operator*(A1, A2) 返回一个临时变量,也是 operator*(A3, A4), operator*(A5, A6)
临时变量的生命周期有什么问题吗?我正在开发一个矩阵类。
如果表达式更复杂会发生什么,例如:
(A+B*C)*((A*B + C)*A)
一般问题是(取自return by rvalue reference)
这可能吗:
改变
A compute(A&& v)
{
(do something to v)
return v;
}
到
A& compute(A& v)
{
(do something to v)
return v;
}
【问题讨论】:
-
我知道这只是一个示例,但是您是否尝试过编译和运行该代码?除了一些语法错误之外,它从不复制任何对象,也从不创建任何临时变量。
-
operator*的用法相当奇怪,因为您实际上实现了operator*=。只需正确定义operator*(即返回一个对象,而不是一个引用)。 -
感谢斯特凡。 operator* 只是显示我的问题的一个示例:返回对通过引用传递的输入变量的引用是否合法
-
@liangbright:是的,这就是你实际实现
operator*=或operator<<的方式。但是,您不应该做的是返回对临时对象的引用。 -
@stefan 谢谢。我更新了示例并在 vs2013 中进行了测试。尽管临时对象是通过引用传递的,但它给出了正确的答案。在我真正的 Matrix 类中,我确实需要创建一些临时对象。我可以按值从函数中返回它们(使用 std::move),并通过引用将它们传递给函数。但是如果我通过引用传递并返回它们,则不会复制任何对象->节省时间。我在vs2013上测试了我的课程,很好。但不知道是c++11标准还是只有vs2013支持。
标签: c++11 object-lifetime