我尝试将unique_ptr
用于SDL_Surface
类型的自定义删除工具。这只是使用int
类型的示例,但我希望您明白这一点。
#include <iostream>
#include <functional>
#include <memory>
typedef int SDL_Surface;
SDL_Surface * CreateSurface()
{
SDL_Surface * p = new SDL_Surface;
return p;
}
void FreeSurface(SDL_Surface *p)
{
delete p;
}
int main() {
std::unique_ptr<SDL_Surface, std::function< void (SDL_Surface *) > > uptr_1;
//how to assign a value to uptr_1 and the deleter?
return 0;
}
uptr_1
是否已正确声明并初始化为nullptr
?如果是这样,我如何分配指针和删除功能?
我该怎么封装呢:
带有删除器的std::unique_ptr< SDL_Surface, std::function< void (SDL_Surface *) > >
并不总是在我想要的每个SDL_Surface
上写一行,另一个是typedef?
我刚刚开始学习C ++ 11的功能,这对我来说很难。
答案 0 :(得分:11)
您可以使用指针和删除器初始化unique_ptr
,或者如果稍后重新分配,则可以正常使用=
:
std::unique_ptr<SDL_Surface, std::function<void (SDL_Surface *)>> uptr_1(CreateSurface(), &FreeSurface);
uptr_1 = std::unique_ptr<SDL_Surface, std::function<void (SDL_Surface *)>>(CreateSurface(), &FreeSurface);
有关详细信息,请参阅suitable docs。
要缩短long类型,您确实可以使用类型别名(typedef
或using
):
typedef std::unique_ptr<SDL_Surface, void (*)(SDL_Surface*)> Surface_ptr;
//or
using Surface_ptr = std::unique_ptr<SDL_Surface, void (*)(SDL_Surface*)>;
注意我实际上已将void (*)(SDL_Surface*)
用于删除器类型。如果你知道你总是传递一个实际函数(或无状态lambda),那么就没有理由拖入std::function
,因为类型擦除会产生一些开销。
此外,您可以通过为删除器创建默认构造函子来进一步缩短它:
struct FreeSurface_Functor
{
void operator() (SDL_Surface *s) const
{
FreeSurface(s);
}
};
这样,您可以指定指针std::unique_ptr<SDL_Surface, FreeSurface_Functor>
的类型(可能是别名),而不必提供删除器;它将是默认构造的:
std::unique_ptr<SDL_Surface, FreeSurface_Functor> uptr_1(CreateSurface());
答案 1 :(得分:2)
我会选择decltype
:
std::unique_ptr<SDL_Surface, decltype(&FreeSurface)> uptr_1(
CreateSurface(),
FreeSurface
);
答案 2 :(得分:1)
uptr_1是否正确声明并初始化为nullptr
是的,默认构造的unique_ptr
将引用null。
如果是这样,我该如何分配指针和删除函数?
您应该使用参数构建unique_ptr
std::unique_ptr<SDL_Surface, std::function< void (SDL_Surface *) > > uptr_1{CreateSurface(), FreeSurface};
或者,在默认构造之后,您可以使用带有临时
的移动分配uptr_1 = std::unique_ptr<SDL_Surface, std::function< void (SDL_Surface *) > >{CreateSurface(), FreeSurface};
正如您自己建议的那样,类型别名可以提供帮助
using SDL_Uptr = std::unique_ptr<SDL_Surface, std::function< void (SDL_Surface *)>>;
SDL_Uptr uptr_1;
uptr_1 = SDL_Uptr{CreateSurface(), FreeSurface};
一个中间函数可以帮助简化它,如果它变得重复(如果你做了很多它可能会这样)。
std::unique_ptr<SDL_Surface, void (*)(SDL_Surface *)>
make_sdl_ptr() {
return std::unique_ptr<SDL_Surface, void (*)(SDL_Surface *)>{CreateSurface(), FreeSurface};
}
然后,您可以使用auto uptr = make_sdl_ptr();
Angew用DefaultConstructible删除器调用你的函数的答案也是一个非常好的解决方案。