按值 return 包含成员向量的对象是个坏主意吗?

Is it a bad idea to return an object by value that contains a member vector?

短版:

如果我的对象包含 std::vector,是否同样的经验法则适用于 return 按值对该对象进行 return 按值对向量进行?

这在 C++11 中有变化吗,据我所知 "guarantees" return按值处理向量很快?

长版:

我有一个小包装 class,其中包含一个 std::vector。

class gf255_poly
{
    public:

        // ... Lots of polynomial methods

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

我想 return 这个 class 的实例来自某些函数,例如:

// 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;
}

我找到了很多关于 and whether it is still a bad design pattern 到 return 和 std::vector 的信息(似乎在大多数情况下都可以)。不过,我还没有发现很多包含作为较大对象成员的向量的内容。

同样的建议是否适用?我是否需要在我的复制构造函数中做任何特殊的事情来帮助确保 return 值优化?

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

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

这是比 返回值优化 更新的创新,但肯定由现代编译器实现,无论它们针对的是哪种 C++ 标准。明确地说,NRVO 不是 C++11 特定的东西。

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

这取决于你的编译器有多聪明(通常很多)。因此,无论您使用什么现代编译器,它都应该是"safe"。

  • < c++11,你应该依赖编译器做Return值优化。

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

您需要(可能默认)在 class 中移动构造函数以启用此行为。

你也可以使用=default on move构造函数。(但是visual studio 2008好像没有这个功能)