按值包含成员向量返回对象是一个坏主意吗?

时间:2016-09-09 14:58:44

标签: c++ visual-studio-2008 stdvector rvo

简短版:

如果我的对象包含std :: vector,那么应用相同的经验法则来应用按值返回该对象以按值返回向量吗?

这是否会在C ++ 11中发生变化,我理解并且#34;保证"按值返回向量是否很快?

长版:

我有一个包含std :: vector的小包装类。

class gf255_poly
{
    public:

        // ... Lots of polynomial methods

    protected:
        std::vector<unsigned char> p;
};

我想从某些功能中返回此类的实例,例如:

// Performs polynomial addition in GF(2^8). 
gf255_poly gf255_poly_add(const gf255_poly &poly1, const gf255_poly &poly2) const
{
    // Initialize:
    gf255_poly dst = poly1;

    // Add all coefficients of poly1 to poly2, respecting degree (the usual polynomial addition)
    for (int deg = 0; deg <= poly2.degree(); deg++)
        dst.addAt(deg, poly2.coef(deg));

    return dst;
}

我已经在how to return a member vectorwhether it is still a bad design pattern找到了大量关于返回std :: vector的信息(在大多数情况下,这似乎很好)。然而,我还没有发现很多包含大型物体成员的矢量。

同样的建议是否适用?我是否需要在复制构造函数中执行任何特殊操作以帮助确保返回值优化?

对于不同版本的C ++标准,这个问题的答案是否有所不同?

3 个答案:

答案 0 :(得分:2)

您的写作gf255_poly dst = poly1;后跟return dst;正在利用命名的返回值优化(NRVO)。

这是一项比返回值优化更新的创新,但无论其目标是什么,它都可以由现代编译器实现。为了绝对清楚,NRVO 不是特定的C ++ 11。

利用NRVO 是一个糟糕的设计选择,因为使用它可以使源代码更易于阅读和维护。

答案 1 :(得分:1)

  • &LT; c ++ 11,你应该依靠编译器来做返回值优化。

  • &gt; = c ++ 11,即使编译器未能(或不能)执行RVO,您也可以使用移动语义来保持代码快速。

您需要在类中使用(可能是默认的)移动构造函数来启用此行为。

您还可以在移动构造函数上使用=default。(但Visual Studio 2008似乎没有此功能)

答案 2 :(得分:0)

这取决于你的编译器有多聪明(通常很多)。所以应该是'#34;安全&#34;在你正在使用的任何现代编译器上。