【问题标题】:when to use custom deleter for std::shared_ptr何时对 std::shared_ptr 使用自定义删除器
【发布时间】:2013-10-10 06:54:32
【问题描述】:

我正在使用 C++ std::shared_ptr 并想知道除了覆盖删除 ptr 之外,自定义删除器是否还有其他用途。或者建议为shared_ptr提供自定义delter的场景是什么

【问题讨论】:

  • 它通常与返回不透明指针或需要特殊删除功能的库一起使用 - 例如Foo* CreateFoo()/void DeleteFoo(Foo*)。

标签: c++


【解决方案1】:

并非所有内存都分配有new,并且内存不是唯一需要释放的资源,例如

std::shared_ptr<FILE> open_file(const std::String& path, const std::String& mode)
{
  if (FILE* f = :fopen(path.c_str(), mode.c_str()))
    return std::shared_ptr<FILE>(f, ::fclose);
  throw std::runtime_error("Cannot open file");
}

【讨论】:

    【解决方案2】:

    您不一定需要明确地拼出删除符。但是该类需要具有允许各种类型擦除的功能,例如从任何unique_ptr&lt;T, D&gt; 构造一个shared_ptr&lt;T&gt;,以及从任何shared_ptr&lt;T&gt; 构造一个shared_ptr&lt;void&gt;。当您第一次创建对象时,默认删除器就在那里,它们会随着所有这些转换传播。

    您有时可以对其他类型的resource management 使用自定义删除器,但大多数情况下unique_ptr 可能更适合这些情况。

    【讨论】:

      【解决方案3】:

      当delete 无法执行您想要的操作时,您需要一个自定义删除器。考虑不同的场景:

      您从池中获取内存并使用placement new 来创建对象。在不是用new 创建的对象上调用delete 将是未定义的行为,因此您需要插入一个将使用适当内存池的删除器。这适用于使用malloc 获取并使用free 释放的内存,例如,或任何其他类型的内存分配器。这也适用于从不同堆获取的内存。

      资源根本不是内存,而是文件描述符、数据库连接等。删除器需要在没有对该资源的引用时释放资源,但释放资源不涉及调用delete,但还有其他一些操作。

      【讨论】:

        【解决方案4】:

        据我所知,删除器实现了两个目标。

        1. 给你一个覆盖delete ptr;的方法(如你所说)。
        2. 使前向声明类无法使用 shared_ptr 和 unique_ptr。

        【讨论】:

        • 你不需要自定义删除器来使用不完整类型的shared_ptr,类型只需要在你第一次初始化shared_ptr时是完整的(通常是这种情况,因为你'那时刚刚分配了对象,所以类型必须是完整的)
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-11-17
        • 1970-01-01
        • 2020-06-19
        • 1970-01-01
        • 1970-01-01
        • 2015-02-28
        • 1970-01-01
        相关资源
        最近更新 更多