使用unique_ptr和自定义删除器混淆

Fra*_*fer 7 c++ unique-ptr c++11

我正在尝试使用类型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;
}
Run Code Online (Sandbox Code Playgroud)

是否uptr_1正确声明并初始化为nullptr?如果是这样,我如何分配指针和删除功能?

我怎么能封装这个: std::unique_ptr< SDL_Surface, std::function< void (SDL_Surface *) > >删除器并不总是在SDL_Surface我想要的每一行上写下那行,另一个是typedef?

我刚开始学习C++ 11的功能,这对我来说很难.

Rei*_*ica 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);
Run Code Online (Sandbox Code Playgroud)

有关详细信息,请参阅合适的文档.

要缩短long类型,您确实可以使用类型别名(typedefusing):

typedef std::unique_ptr<SDL_Surface, void (*)(SDL_Surface*)> Surface_ptr;

//or

using Surface_ptr = std::unique_ptr<SDL_Surface, void (*)(SDL_Surface*)>;
Run Code Online (Sandbox Code Playgroud)

注意我实际上用于void (*)(SDL_Surface*)删除类型.如果你知道你总是会传递一个实际函数(或无状态lambda),那么没有理由拖入std::function,因为类型擦除会产生一些开销.

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

struct FreeSurface_Functor
{
  void operator() (SDL_Surface *s) const
  {
    FreeSurface(s);
  }
};
Run Code Online (Sandbox Code Playgroud)

这样,您可以创建指针的类型std::unique_ptr<SDL_Surface, FreeSurface_Functor>(可能是别名),而不必提供删除器; 它将是默认构造的:

std::unique_ptr<SDL_Surface, FreeSurface_Functor> uptr_1(CreateSurface());
Run Code Online (Sandbox Code Playgroud)

  • 您可能会指出定义无状态删除器类类型的技术是首选,因为质量`unique_ptr`实现将使用空基优化来优化其存储. (5认同)