在方法中返回静态变量是个坏主意吗?

时间:2015-12-16 12:33:11

标签: c++ variables static return

我四处搜寻,似乎找不到我的问题的答案。我正在做一个项目,我必须重新定义一些运算符(+-*等),以便在向量和多项式之间进行操作。据我所知,这些运算符应该返回对象的副本,以便在我们只是调用运算符(即vect1+vect2;而不是vect1 += vect2;)而不是放置它时不直接修改它们。结果随处可见

现在,我已经看到使用静态变量的所有方法都是不好的做法,但是当方法需要返回结果的副本而不是修改对象时,我怎么能避免这样做呢?

问题herehere并没有真正帮助,因为它们没有解决我的特定问题。

这是我的意思的一个例子:

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。有没有办法这样做呢?

2 个答案:

答案 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。虽然这个例子是设计的,但它只是你可能对+做的许多事情中的一个,如果它返回对静态的引用则会出现可怕的错误。