0

我是在传递结构的日子里长大的,因为它们通常很大,所以指针总是要走的路。现在 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;
    }
};
4

2 回答 2

0

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

指南:不要复制你的函数参数。相反,按值传递它们并让编译器进行复制

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

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
于 2013-08-04T21:57:10.330 回答
0

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

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

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

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

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

于 2013-08-04T22:02:32.637 回答