Lambda捕获shared_ptr成员

时间:2013-10-22 21:07:14

标签: c++ memory-management c++11 lambda smart-pointers

我有一个班级OpenGLRenderer,其成员mMemoryAllocatorstd::shared_ptr<MemoryAllocator>。我将内存分配器保留在shared_ptr中的原因是因为即使下面返回的shared_ptr<Texture>比它的创建者OpenGLRenderer更长,如果我按值捕获它,MemoryAllocator实例仍然有效,因为它增加了引用计数:

std::shared_ptr<Texture> OpenGLRenderer::CreateTexture(TextureType textureType, const std::vector<uint8_t>& textureData, uint32_t textureWidth, uint32_t textureHeight, TextureFormat textureFormat)
{
    return std::shared_ptr<Texture>(mMemoryAllocator->AllocateObject<Texture>(
                                    textureData, textureWidth, textureHeight,
                                    textureFormat, textureType, mLogger), 
                                    [=](Texture* texture) { 
                                        mMemoryAllocator
                                         ->DeallocateObject<Texture>(texture); 
                                    });
}

......但是,它不起作用。如果OpenGLRenderer超出std::shared_ptr<Texture>之前的范围,则std::shared_ptr<MemoryAllocator>会被破坏,因此lambda表达式会变得疯狂。我做错了什么?

1 个答案:

答案 0 :(得分:11)

这种情况下的问题是lambdas不会捕获对象的成员,而是this指针。一个简单的解决方法是创建一个局部变量并绑定:

std::shared_ptr<Texture> 
OpenGLRenderer::CreateTexture(TextureType textureType, 
                              const std::vector<uint8_t>& textureData, 
                              uint32_t textureWidth, uint32_t textureHeight, 
                              TextureFormat textureFormat)

{
    std::shared_ptr<AllocatorType> allocator = mMemoryAllocator;
    return std::shared_ptr<Texture>(mMemoryAllocator->AllocateObject<Texture>(
                                    textureData, textureWidth, textureHeight,
                                    textureFormat, textureType, mLogger), 
                                    [=](Texture* texture) { 
                                        allocator
                                         ->DeallocateObject<Texture>(texture); 
                                    });
}