2013-08-04 31 views
0

我在成长过程中经历过的结构是恶魔,因为它们往往很大,所以指针总是要走的路。既然C++ 11具有相当好的RVO(右值优化),我想知道下面的代码是否有效。你可以看到,我的类有一堆向量结构(不是指向它们的指针)。构造函数接受值结构并将其存储。用C++ 11中的RVO优化此风格的代码吗?

我-hope-是编译器将使用移动语义,以便确实没有数据复制正在进行;构造函数会(如果可能)只承担传递的值的所有权。

有谁知道,如果这是真的,偏偏自动的,或者我需要用& &语法等方面的举动构造?

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

请在构造函数中使用初始化列表,而不是其正文中的分配。 – Manu343726

+1

RVO代表返回值优化。 – Rapptz

+1

'D3DXVECTOR4'接口和实现问题,以确定如何通过它。在这种情况下,'D3DXVECTOR4'是一个4'float'的POD'struct'。 'std :: move'和'&&'对它的处理方式几乎没有影响。 – Yakk

回答

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 
+4

'move'不会在这里保存任何东西 - 这些结构是聚合。 –

+0

@BillyONeal我实际上没有做D3DX编程。在这种情况下,这个问题似乎是......不适当的。我的答案应该解释一般情况(例如,当通过'ParticleVertex'对象时)和检查生成的代码总是胜过任何指导:) – sehe

+0

现在我有点困惑 - 如果我使用VS2012,它支持C++ 11,你什么时候需要构造函数中的std :: move()? 我可以检查生成的程序集,但我更愿意从语言规范和编译器支持知道实际发生的事情。 – Dave

0

RVO意味着返回值优化不正确的价值优化。

RVO是由编译器在函数的返回值为值时执行的优化,它清楚地表明代码返回在主体中创建的临时对象,因此可以避免副本。该函数直接返回创建的对象。

C++ 11引入的是什么移动语义。移动语义允许我们将资源从某个临时“移动”到目标对象。
但是,移动意味着资源所属的对象来自移动后处于不可用状态。在你的课堂中,你并不需要这种情况(我认为),因为即使用户调用该函数,该类也会使用顶点数据。 因此,使用const引用的常见返回来避免副本。

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

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