C++:返回共享指针会破坏对象
我试图shared_ptr从一个方法返回一个新的:
std::shared_ptr<VertexBuffer> VertexBuffer::Create(float* vertices, uint32_t size)
{
return std::make_shared<OpenGLVertexBuffer>(std::move(OpenGLVertexBuffer(vertices, size)));
}
我有一个析构函数并VertexBuffer在退出此方法后被销毁。这是为什么?
回答
正在此临时对象上调用析构函数:
return std::make_shared<OpenGLVertexBuffer>(std::move(OpenGLVertexBuffer(vertices, size)));
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
您稍微滥用std::make_shared并调用了移动/复制构造函数。如果您的班级遵循三/五/零规则,这不应该是正确性问题,但效率低下。
相反,您应该std::make_shared按预期使用直接构造对象,即转发构造函数参数而不是显式构造对象。
return std::make_shared<OpenGLVertexBuffer>(vertices, size);
另请注意,调用std::move(x)wherex已经是临时的没有任何作用。
- _“另请注意,调用 `std::move(x)`,其中 `x` 已经是临时的了。”_ -- 实际上,这种做法可能比什么都不做更糟糕。在 C++17 中,这种做法可以防止复制省略,因为它将 PRValue 转换为 XValue。这并不适用于这种确切的情况,因为 `std::make_shared` 无论如何都会转发引用,但如果它在这里完成,它很可能在其他地方完成。