【发布时间】:2013-10-10 06:54:32
【问题描述】:
我正在使用 C++ std::shared_ptr 并想知道除了覆盖删除 ptr 之外,自定义删除器是否还有其他用途。或者建议为shared_ptr提供自定义delter的场景是什么
【问题讨论】:
-
它通常与返回不透明指针或需要特殊删除功能的库一起使用 - 例如
Foo* CreateFoo()/void DeleteFoo(Foo*)。
标签: c++
我正在使用 C++ std::shared_ptr 并想知道除了覆盖删除 ptr 之外,自定义删除器是否还有其他用途。或者建议为shared_ptr提供自定义delter的场景是什么
【问题讨论】:
Foo* CreateFoo()/void DeleteFoo(Foo*)。
标签: c++
并非所有内存都分配有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");
}
【讨论】:
您不一定需要明确地拼出删除符。但是该类需要具有允许各种类型擦除的功能,例如从任何unique_ptr<T, D> 构造一个shared_ptr<T>,以及从任何shared_ptr<T> 构造一个shared_ptr<void>。当您第一次创建对象时,默认删除器就在那里,它们会随着所有这些转换传播。
您有时可以对其他类型的resource management 使用自定义删除器,但大多数情况下unique_ptr 可能更适合这些情况。
【讨论】:
当delete 无法执行您想要的操作时,您需要一个自定义删除器。考虑不同的场景:
您从池中获取内存并使用placement new 来创建对象。在不是用new 创建的对象上调用delete 将是未定义的行为,因此您需要插入一个将使用适当内存池的删除器。这适用于使用malloc 获取并使用free 释放的内存,例如,或任何其他类型的内存分配器。这也适用于从不同堆获取的内存。
资源根本不是内存,而是文件描述符、数据库连接等。删除器需要在没有对该资源的引用时释放资源,但释放资源不涉及调用delete,但还有其他一些操作。
【讨论】:
据我所知,删除器实现了两个目标。
delete ptr;的方法(如你所说)。【讨论】:
shared_ptr,类型只需要在你第一次初始化shared_ptr时是完整的(通常是这种情况,因为你'那时刚刚分配了对象,所以类型必须是完整的)