C++ 将自定义删除器与 std::shared_ptr 一起使用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12340810/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using custom deleter with std::shared_ptr
提问by Wheels2050
I'm trying to work out how to use std::shared_ptr with a custom deleter. Specifically, I'm using it with SDL_Surface as:
我正在尝试研究如何将 std::shared_ptr 与自定义删除器一起使用。具体来说,我将它与 SDL_Surface 一起使用:
std::shared_ptr<SDL_Surface>(SDL_LoadBMP(....),SDL_FreeSurface);
which compiles and runs fine. However, I would like to try out my own deleter and cannot work out how to do so. The documentation for SDL_FreeSurface is found here:
它编译并运行良好。但是,我想尝试一下自己的删除器,但不知道该怎么做。SDL_FreeSurface 的文档可以在这里找到:
http://sdl.beuc.net/sdl.wiki/SDL_FreeSurface
http://sdl.beuc.net/sdl.wiki/SDL_FreeSurface
in which I find the SDL_FreeSurface is declared as:
在其中我发现 SDL_FreeSurface 被声明为:
void SDL_FreeSurface(SDL_Surface* surface);
As a test, and going by that information, I tried the following function:
作为测试,并根据该信息,我尝试了以下功能:
void DeleteSurface(SDL_Surface* surface)
{
std::cout << "Deleting surface\n";
SDL_FreeSurface(surface);
}
However, compiling with g++ gives me the following error:
但是,使用 g++ 编译会给我以下错误:
error: no matching function for call to 'std::shared_ptr<SDL_Surface>::shared_ptr(SDL_Surface*, <unresolved overloaded function type>)'
I have looked at the gnu documentation for the gcc std::shared_ptr implementation but cannot make much sense of it. What am I doing wrong?
我已经查看了 gcc std::shared_ptr 实现的 gnu 文档,但无法理解它。我究竟做错了什么?
EDIT: I've since narrowed down the problem, but will leave the original question above. What I had was a Game class which, if I strip it down to a basic implementation, was something like:
编辑:我已经缩小了问题的范围,但会保留上面的原始问题。我拥有的是一个 Game 类,如果我将其分解为基本实现,则类似于:
class Game {
public:
/* various functions */
private:
void DeleteSurface(SDL_Surface* surface);
bool CacheImages();
std::vector<std::shared_ptr<SDL_Surface> > mCachedImages;
/* various member variables and other functions */
}
with the implementation of DeleteSurface
as above, and the implementation of CacheImages()
as:
与上述的实施DeleteSurface
,并实施CacheImages()
为:
bool CacheImages()
{
mCachedImages.push_back(std::shared_ptr<SDL_Surface>(SDL_LoadBMP(...),DeleteSurface);
return true;
}
which game me the error I listed above. However, if I move the DeleteSurface()
function outside the Game
class without otherwise altering it, the code compiles. What is it about including the DeleteSurface
function in the Game
class that is causing problems?
哪个游戏我上面列出的错误。但是,如果我将DeleteSurface()
函数移到Game
类之外而不更改它,则代码会编译。DeleteSurface
在Game
导致问题的类中包含函数是什么意思?
回答by ronag
std::shared_ptr<SDL_Surface>(SDL_LoadBMP(....), [=](SDL_Surface* surface)
{
std::cout << "Deleting surface\n";
SDL_FreeSurface(surface);
});
or
或者
void DeleteSurface(SDL_Surface* surface)
{
std::cout << "Deleting surface\n";
SDL_FreeSurface(surface);
}
std::shared_ptr<SDL_Surface>(SDL_LoadBMP(....), DeleteSurface);
EDIT:
编辑:
Seeing your updated question, DeleteSurface
should be a non-member function, otherwise you need to use std::bind
or std::mem_fn
or some other member function pointer adapter.
看到您更新的问题,DeleteSurface
应该是非成员函数,否则您需要使用std::bind
或std::mem_fn
或其他一些成员函数指针适配器。
回答by chmike
This code provides an example of a shared pointer construction with the deleter as an object method. It display the std::bind
instruction to use.
此代码提供了一个以删除器作为对象方法的共享指针构造示例。它显示使用std::bind
说明。
The example is a simple object recycler. When the last reference to the object is destroyed, the object is returned to the free object pool inside the recycler.
该示例是一个简单的对象回收器。当对对象的最后一个引用被销毁时,该对象将返回到回收器内部的空闲对象池中。
The recyler can be easily changed into an object cache by adding a key to the get()
and add()
methods and by storing the objects in a std::map
.
通过向get()
和add()
方法添加键并将对象存储在std::map
.
class ObjRecycler
{
private:
std::vector<Obj*> freeObjPool;
public:
~ObjRecycler()
{
for (auto o: freeObjPool)
delete o;
}
void add(Obj *o)
{
if (o)
freeObjPool.push_back(o);
}
std::shared_ptr<Obj> get()
{
Obj* o;
if (freeObjPool.empty())
o = new Obj();
else
{
o = freeObjPool.back();
freeObjPool.pop_back();
}
return std::shared_ptr<Obj>(o,
std::bind(&ObjRecycler::add, this, std::placeholders::_1));
}
}