【发布时间】:2015-02-04 12:48:34
【问题描述】:
我已经阅读了许多关于shared_ptr 和unique_ptr 的自定义删除器的 SO 问题,以及两者之间的区别。但是,我仍然没有找到任何明确的答案:
如何最好地使用自定义删除器创建一个充当shared_ptr 的类型,类似于unique_ptr 将删除器作为类型定义的一部分?
对于unique_ptr 的用法,我使用了一个删除器类,它处理单个类型的删除(为简洁起见,将其限制为两种类型):
struct SDL_Deleter {
void operator()( SDL_Surface* ptr ) { if (ptr) SDL_FreeSurface( ptr );}
void operator()( SDL_RWops* ptr ) { if (ptr) SDL_RWclose( ptr );}
};
using SurfacePtr = std::unique_ptr<SDL_Surface, SDL_Deleter>;
using RWopsPtr = std::unique_ptr<SDL_RWops, SDL_Deleter>;
这可以与类似的东西一起使用
SurfacePtr surface(IMG_Load("image.png"));
并且会在销毁时调用SDL_FreeSurface。
这一切都很好。但是,如何为shared_ptr 实现相同的目标?它的类型定义为
template< class T > class shared_ptr;
提供自定义删除器的方法是通过构造函数。 shared_ptr 包装器的用户需要知道包装了哪种指针类型以及应该如何删除该指针,这感觉不对。实现与上述unique_ptr 示例相同的用法的最佳方法是什么。
换句话说,我最终会得到:
SurfaceShPtr surface(IMG_Load("image.png"));
而不是类似的东西
SurfaceShPtr surface(IMG_Load("image.png"),
[=](SDL_Surface* ptr){SDL_FreeSurface(ptr);});
或者,稍微好一点
SurfaceShPtr surface(IMG_Load("image.png"),
SDL_Deleter());
有没有办法做到这一点,而不必创建 RAII 包装类(而不是 typedef),从而增加更多开销?
如果答案是“这不可能”。为什么不呢?
【问题讨论】:
-
search on this site 产生 nothing 有用吗?
-
@WhozCraig 是的。我做到了。如果您发现我遗漏的内容,可以将其标记为重复。
-
@JonathanWakely 如果您想告诉我如何操作,我将不胜感激。
-
unique_ptr<SDL_Surface, decltype(&SDL_FreeSurface)> p(IMG_load("image.png", &SDL_FreeSurface); -
或查看我的答案的更新。我决定对所有内容都使用一个删除器类型,而不是类模板。
标签: c++ shared-ptr smart-pointers unique-ptr raii