将可释放对象包装到智能指针中

时间:2015-10-14 08:16:16

标签: c++ templates pointers

据我了解智能指针,它们可以避免内存泄漏。但是,通常还需要释放对象,但不能由freedelete释放。是否有一些通用的方法将这些指针与模板一起使用?

作为示例FILE浮现在脑海中,完成时应使用fclose。当然还有其他类型的指针具有自己独特的释放功能。那么我是否必须实施单独的包装来解释他们的个人发布方法,还是有更好的方法来做到这一点?

可以像这样使用的东西:

smart_ptr<FILE, fclose> fl = fopen();
smart_ptr<IStream, T->Release> pFileStream = SHCreateStreamOnFile(...);

3 个答案:

答案 0 :(得分:1)

如果您使用的是unique_ptrshared_ptr,则可以提供自定义删除工具。 unique_ptr的删除器作为模板参数传递,

  

Deleter必须是对函数的FunctionObject或左值引用的FunctionObject或左值引用,可以使用unique_ptr<T, Deleter>::pointer类型的参数调用

对于shated_ptr,删除器应作为构造函数参数提供。

class Foo
{

};

class Deleter
{
public:
    void operator()(Foo *)
    {
        std::cout << "deleter";
    }
};

int main() {
    std::unique_ptr<Foo, Deleter> ptr(new Foo());
    std::shared_ptr<Foo> ptr1(new Foo(),
                             [](Foo*){std::cout << "deleter for shared_ptr";}
                             );
}

但是,你必须小心不要造成内存泄漏。

答案 1 :(得分:0)

shared_ptrunique_ptr都提供了这种便利。

对于shared_ptr,构造函数是一个模板:

  

可以提供一个可选的删除器d,当没有shared_ptr对象拥有它时,该删除器d稍后用于销毁该对象。默认情况下,类型Y的delete-expression用作删除器。

在这种情况下,删除器可以是任何可调用的,可复制构造 ,它将被类型擦除到可调用状态。

对于unique_ptr,删除器的类型是指针本身的类型参数:

template<
    class T,
    class Deleter = std::default_delete<T>
> class unique_ptr;

在这种情况下没有擦除,提供给c-tor或删除的删除器实际上与删除器类型匹配。

答案 2 :(得分:0)

您可以使用自定义删除工具构建shared_ptr(签名#3 here)和unique_ptr(签名#2 here)。

using T = ...;
auto deleter = [](T* x) { delete x; };

// different deleter - different unique_ptr type
// deleter is stored inline
auto x = std::unique_ptr<T, decltype(deleter)>(new T(...), deleter);

// same shared_ptr<T> type regardless of the deleter type,
// deleter is stored in the "shared state"
auto y = std::shared_ptr<T>(new T(...), deleter);

注意,make_shared()不能用于构建带有自定义删除工具的shared_ptr