我四处搜寻,似乎找不到我的问题的答案。我正在做一个项目,我必须重新定义一些运算符(+
,-
,*
等),以便在向量和多项式之间进行操作。据我所知,这些运算符应该返回对象的副本,以便在我们只是调用运算符(即vect1+vect2;
而不是vect1 += vect2;
)而不是放置它时不直接修改它们。结果随处可见
现在,我已经看到使用静态变量的所有方法都是不好的做法,但是当方法需要返回结果的副本而不是修改对象时,我怎么能避免这样做呢?
问题here和here并没有真正帮助,因为它们没有解决我的特定问题。
这是我的意思的一个例子:
template <class elem>
Vect_variable<elem>& Vect_variable<elem>::operator+(const Vect_variable& operand)
{
if (taille >= operand.taille)
{
static Vect_variable<elem> temp_v;
temp_v = *this;
for (std::size_t i = 0; i<operand.taille; i++)
{
temp_v[i] += operand.vecteur[i];
}
return temp_v;
}
else
{
static Vect_variable<elem> temp_v;
temp_v = operand;
for(std::size_t i = 0; i<taille; i++)
{
temp_v[i] += vecteur[i];
}
return temp_v;
}
}
在这种情况下,您可以看到我正在为使用的临时变量创建静态Vect_variable
。有没有办法这样做呢?
答案 0 :(得分:4)
是。不要变量static
。这样每次调用函数都会获得自己的新变量,然后返回。
此外,它是自动的(在堆栈上)而不是静态的,您可以声明变量并一次性初始化它。
...而且我没有注意到你正在向载体返回引用。不要这样做。按价值归还。
template <class elem>
Vect_variable<elem> Vect_variable<elem>::operator+(const Vect_variable& operand)
{
if (taille >= operand.taille)
{
Vect_variable<elem> temp_v = *this;
for (std::size_t i = 0; i<operand.taille; i++)
{
temp_v[i] += operand.vecteur[i];
}
return temp_v;
}
else
{
Vect_variable<elem> temp_v = operand;
for(std::size_t i = 0; i<taille; i++)
{
temp_v[i] += vecteur[i];
}
return temp_v;
}
}
接下来要做的是注意到你在两个分支中做几乎同样的事情。这取决于哪个尾部更短。所以使用一对指针:
{
decltype(this) one, two;
if (taille >= operand.taille)
{
one = this;
two = &operand;
}
else
{
one = &operand;
two = this;
}
Vect_variable<elem> temp_v = *one;
for (std::size_t i = 0; i<two->taille; i++)
{
temp_v[i] += two->vecteur[i];
}
return temp_v;
}
最后的评论是,通常首先编写operator +=
,然后将operator +
写为具有签名的非成员二进制函数,这是一种好习惯:
TYPE operator +(TYPE lhs, const TYPE& rhs)
{
lhs += rhs;
return lhs;
}
请注意lhs
取自值(因此您已拥有自己的副本)。非成员函数的优点是,如果你有TYPE
的任何转换函数,它们将在左侧和右侧对称运行。
答案 1 :(得分:2)
强大而简单的方法是按值返回(非静态)局部变量。在某些情况下,这也是有效的方法。
如果您非常关心效率,那么您需要一个备用执行路径,用于两个输入中的一个是右值的情况。在这种情况下,您根本不需要局部变量。相反,您希望通过右值引用获取输入,修改它并通过右值引用返回它。
为避免重复代码过多,您可能需要定义operator+=
并将实际工作放在该方法中,并让所有版本的operator+
将工作委托给operator+=
< / p>
在某些情况下,通过引用返回static
变量比上述所有更有效。但是没有很多这样的情况,并且它们充满了足够的危险,你不应该做出这样的选择。
看过你在前面的回答中所做的评论:你是正确的,通过引用返回static
避免了从超越虚拟函数返回多态的大问题。但它是以牺牲创造自己的问题为代价的。对于一个简单的示例,请考虑使用您的+
计算A+(B+C)
的人。不要问为什么他们放入那些不合适的()
。只是意识到他们无法知道他们不应该这样做。因此,您的运营商会将B
复制到静态并向其添加C
,然后将A
复制到相同的静态,并将静态添加到该静态并返回2A
。虽然这个例子是设计的,但它只是你可能对+
做的许多事情中的一个,如果它返回对静态的引用则会出现可怕的错误。