使用.reset()释放具有唯一所有权的boost::shared_ptr

7

我正在使用由第三方API提供的shared_ptr存储一个对象(TTF_Font)。由于无法在对象上使用new或delete,因此shared_ptr还提供了一个“释放”函数。

// Functor
struct CloseFont
{
    void operator()(TTF_Font* font) const
    {
        if(font != NULL) {
            TTF_CloseFont(font);
        }
    }
};

boost::shared_ptr<TTF_Font> screenFont;

screenFont = boost::shared_ptr<TTF_Font>( TTF_OpenFont("slkscr.ttf", 8), CloseFont() );

如果以后我需要显式释放这个对象,这样做是否正确:

screenFont.reset();

那么让 screenFont(实际的 shared_ptr 对象)自然销毁就可以了吗?

2个回答

16

shared_ptr<>::reset()会使引用计数减一。如果这导致计数降至零,则shared_ptr<>指向的资源将被释放。

因此我认为对你来说,答案是肯定的。或者,如果屏幕字体变量即将超出作用域或其他原因而被销毁,你也可以让它自动释放。

需要明确的是,shared_ptr<>的正常使用方式是让它自然地被销毁,并在其自然降至零时处理引用计数和释放资源。只有在需要释放shared_ptr<>的特定实例之前,才需要使用reset()。


1
感谢您的回复。在我的情况下,我必须在释放另一个资源之前显式地释放它,这是我找到的唯一方法。 - Zack The Human
2
只是为了明确 - reset() 不会释放持有的资源,除非它导致引用计数降至零 - 它不会强制引用计数为零。 - Michael Burr

0
Mike B已经回答了你的问题,所以我只是评论一下你的代码。如果TTF_OpenFont没有返回null,或者TTF_CloseFont可以无害地处理nulls,那么你根本不需要一个CloseFont类,只需使用&TTF_CloseFont即可。

谢谢。这就是我最初所做的。我发现一个与字体资源相关的错误,另一个资源在我的字体资源之前被释放,并尝试通过上述方法解决它。虽然这个错误与函数对象无关,但我保留了它,因为我正在使用相同的模式处理其他资源。 - Zack The Human

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接