C++ 使用唯一的\u ptr和自定义删除器

C++ 使用唯一的\u ptr和自定义删除器,c++,c++11,unique-ptr,C++,C++11,Unique Ptr,我正在尝试将unique\u ptr与SDL\u Surface类型的自定义删除器一起使用。这只是一个使用inttype的示例,但我希望您能理解 #include <iostream> #include <functional> #include <memory> typedef int SDL_Surface; SDL_Surface * CreateSurface() { SDL_Surface * p = new SDL_Surface;

我正在尝试将
unique\u ptr
SDL\u Surface
类型的自定义删除器一起使用。这只是一个使用
int
type的示例,但我希望您能理解

#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;
}
#包括
#包括
#包括
类型定义int SDL_表面;
SDL_曲面*CreateSurface()
{
SDL_曲面*p=新的SDL_曲面;
返回p;
}
空心自由曲面(SDL_曲面*p)
{
删除p;
}
int main(){
std::unique_ptr>uptr_1;
//如何为uptr_1和删除器赋值?
返回0;
}
uptr\u 1
是否正确声明并初始化为
nullptr
?如果是,我如何分配指针和deleter函数

我如何封装这个:
std::unique_ptr
删除程序不总是在每个
SDL_Surface
上写那一行,我想要另一个typedef

我刚刚开始学习C++11的特性,这对我来说是一件很难的事情

uptr_1是否正确声明并初始化为nullptr

是的,默认构造的
unique\u ptr
将引用null

如果是,我如何分配指针和deleter函数

您应该使用参数构造
唯一\u ptr

 std::unique_ptr<SDL_Surface, std::function< void (SDL_Surface *) > > uptr_1{CreateSurface(), FreeSurface};
std::unique_ptr>uptr_1{CreateSurface(),freessurface};
或者,在默认构造之后,可以将移动指定与临时构造一起使用

uptr_1 = std::unique_ptr<SDL_Surface, std::function< void (SDL_Surface *) > >{CreateSurface(), FreeSurface};
uptr_1=std::unique_ptr>{CreateSurface(),freessurface};
正如您自己所建议的,类型别名可以有所帮助

using SDL_Uptr = std::unique_ptr<SDL_Surface, std::function< void (SDL_Surface *)>>;
SDL_Uptr  uptr_1;
uptr_1 = SDL_Uptr{CreateSurface(), FreeSurface};
使用SDL\u Uptr=std::unique\u ptr>;
SDL_Uptr Uptr_1;
uptr_1=SDL_uptr{CreateSurface(),freessurface};
如果中间函数变得重复,它可以帮助简化这个过程(如果你做了很多中间函数,它可能会重复)

std::unique\u ptr
制造sdl ptr(){
返回std::unique_ptr{CreateSurface(),freessurface};
}
然后可以使用
auto-uptr=make_-sdl_-ptr()调用它


Angew用一个调用函数的默认可构造删除程序来回答这个问题也是一个很好的解决方案。

您可以使用指针和删除程序初始化
唯一的\u 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);
注意,我实际上使用了
void(*)(SDL_Surface*)
作为删除器类型。如果您知道总是要传入一个实际函数(或无状态lambda),那么就没有理由拖入
std::function
,因为类型擦除会带来一些开销

此外,您还可以通过为删除程序创建默认的可构造函子来进一步缩短它:

struct FreeSurface_Functor
{
  void operator() (SDL_Surface *s) const
  {
    FreeSurface(s);
  }
};
这样,您就可以使指针的类型
std::unique\u ptr
(可能有别名),而不必提供deleter;它将默认构造为:

std::unique_ptr<SDL_Surface, FreeSurface_Functor> uptr_1(CreateSurface());
std::unique_ptr uptr_1(CreateSurface());

我会选择
decltype

std::unique_ptr<SDL_Surface, decltype(&FreeSurface)> uptr_1(
          CreateSurface(),
          FreeSurface
);
std::唯一的\u ptr uptr\u 1(
CreateSurface(),
自由曲面
);

std::unique\u ptr>uptr\u 1(CreateSurface(),&::FreeSurface)
std::function
对于一般情况下的删除器来说是一个糟糕的选择,因为它的构造函数可以抛出,但是
unique\u ptr
的删除器的构造函数不能抛出。但是,如果您只使用普通函数指针,那么它是安全的。相关的-如果指针为nullptr,我是否需要检查自定义删除程序?或者std::unique\u ptr在指针为nullptr时不会调用默认的删除器?谢谢您的回答。@FrameBuffer您不必检查
unique_ptr
保证为您执行检查,并且仅在非空时调用删除程序。您可以在中找到类似的内容。您可能会指出,最好使用定义无状态删除器类类型的技术,因为quality
unique\u ptr
实现将通过空基优化来优化其存储。
std::unique_ptr<SDL_Surface, FreeSurface_Functor> uptr_1(CreateSurface());
std::unique_ptr<SDL_Surface, decltype(&FreeSurface)> uptr_1(
          CreateSurface(),
          FreeSurface
);