将可释放对象封装到智能指针中
Wrapping a releaseable object into a smart pointer
就我对智能指针的理解而言,它们的存在是为了避免内存泄漏等问题。然而,经常有一些对象也需要被释放,但不是由free
或delete
释放。是否有一些通用的方法使用这样的指针与模板?
以FILE
为例,完成后应使用fclose
。当然,还有其他类型的指针,它们有自己独特的释放函数。那么,我是否必须实现单独的包装器来解释它们各自的发布方法,或者是否有更好的方法来做到这一点?
可以这样使用:
smart_ptr<FILE, fclose> fl = fopen();
smart_ptr<IStream, T->Release> pFileStream = SHCreateStreamOnFile(...);
如果您使用的是unique_ptr
或shared_ptr
,您可以提供您的自定义删除器。unique_ptr
的deleter作为模板参数传递,
Deleter必须是FunctionObject或FunctionObject的左值引用或函数的左值引用,可使用
unique_ptr<T, Deleter>::pointer
类型的参数调用
对于shated_ptr
, deleter应该作为构造函数参数提供。
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";}
);
}
您必须小心不要引起内存泄漏。
shared_ptr
和unique_ptr
都提供这种功能。
对于shared_ptr
,构造函数是模板:
可以提供一个可选的deleter d,当没有shared_ptr对象拥有该对象时,该deleter d用于销毁该对象。默认情况下,使用类型Y的delete表达式作为删除符。
在这种情况下,删除器可以是任何可调用的可复制构造的值,它们被类型擦除为可调用对象。
对于unique_ptr
, deleter的类型是指针本身的类型形参:
template<
class T,
class Deleter = std::default_delete<T>
> class unique_ptr;
在这种情况下没有擦除,并且提供给c-tor或重置的删除器实际上匹配删除器类型。
您可以使用自定义删除器构建shared_ptr
(此处签名#3)和unique_ptr
(此处签名#2)。
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
。
- 1d 智能指针不适用于语法 (*)++
- 优先顺序:智能指针和类析构函数
- 对于C++中使用智能指针的指针算术限制,有没有一种变通方法
- 智能指针作为无序映射键,并通过引用进行比较
- 智能指针概念所有权和寿命
- 正在理解智能指针,但出现错误:未分配正在释放的指针
- 尝试使用智能指针时引发异常
- 我可以制作指向智能指针的智能指针吗?
- 通过智能指针和转换对基本模板参数进行模板推导
- OpenCV 我应该使用智能指针来防止内存泄漏吗?
- 从堆栈分配的原始指针构造智能指针
- 初始化指向类实例的智能指针并访问其方法
- 如何使用 std::make_shared 创建基类类型的智能指针?
- 给定一个指向堆分配内存的指针,智能指针实现如何为其找到合适的释放函数?
- 编译器不会使用 -std=c++11 编译智能指针
- 具有智能指针的多态性
- C++:矢量分配器行为、内存分配和智能指针
- 在什么情况下,需要共享智能指针而无法使用唯一指针?
- 指向函数签名中的常量智能指针
- 使用智能指针附加的继承对象的深层复制