我成长的时代,传递结构是一种糟糕的方式,因为它们通常很大,所以指针总是首选。既然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引用返回。