用这种风格编写的代码会被C++11中的RVO优化吗



我成长的时代,传递结构是一种糟糕的方式,因为它们通常很大,所以指针总是首选。既然C++11有很好的RVO(正确的值优化),我想知道下面这样的代码是否有效。

正如你所看到的,我的类有一堆向量结构(而不是指向它们的指针)。构造函数接受值结构并将其存储起来。

我希望编译器将使用移动语义,这样就不会真正复制数据;构造函数将(在可能的情况下)只承担传入值的所有权。

是否有人知道这是真的,并且自动发生,或者我是否需要一个带有&语法等等?

// ParticleVertex
//
// Class that represents the particle vertices
class ParticleVertex : public Vertex
{
  public:
    D3DXVECTOR4   _vertexPosition;
    D3DXVECTOR2   _vertexTextureCoordinate;
    D3DXVECTOR3   _vertexDirection;
    D3DXVECTOR3   _vertexColorMultipler;
    ParticleVertex(D3DXVECTOR4   vertexPosition,
                   D3DXVECTOR2   vertexTextureCoordinate,
                   D3DXVECTOR3   vertexDirection,
                   D3DXVECTOR3   vertexColorMultipler)
    {
        _vertexPosition          = vertexPosition;
        _vertexTextureCoordinate = vertexTextureCoordinate;
        _vertexDirection         = vertexDirection;
        _vertexColorMultipler    = vertexColorMultipler;
    }
    virtual const D3DVERTEXELEMENT9 * GetVertexDeclaration() const
    {
        return particleVertexDeclarations;
    }
};

是的,您确实应该相信编译器能够以最佳方式"移动"结构:

  • 想要速度?传递值

准则:不要复制你的函数参数。相反,通过值传递它们,并让编译器进行复制

在这种情况下,您可以将参数移动到构造函数调用中:

ParticleVertex myPV(std::move(pos),
               std::move(textureCoordinate),
               std::move(direction),
               std::move(colorMultipler));

在许多情况下,std::move将是隐式,例如

D3DXVECTOR4 getFooPosition() { 
     D3DXVECTOR4 result;
     // bla
     return result; // NRVO, std::move only required with MSVC
}
ParticleVertex myPV(getFooPosition(), // implicit rvalue-reference moved

RVO表示返回值优化不是正确的值优化。

RVO是编译器在函数按值返回时执行的优化,很明显,代码返回在主体中创建的临时对象,因此可以避免复制。函数直接返回创建的对象。

C++11引入的是移动语义。Move语义允许我们将资源从某个临时对象"移动"到目标对象
但是,移动意味着资源来源的对象在移动后处于不可用状态。在类中,情况并非如此(我认为),因为顶点数据由类使用,即使用户是否调用该函数也是如此。因此,请使用const引用的公共返回来避免复制。

另一方面,DirectX提供了资源(指针)的句柄,而不是真正的资源。指针是基本类型,它的复制成本很低,所以不用担心性能。在您的情况下,您使用的是2d/3d矢量。它的复制也很便宜。

就我个人而言,我认为返回一个指向内部资源的指针总是一个非常糟糕的主意。我认为在这种情况下,最好的方法是通过const引用返回。

最新更新