为了教育起见,我试图了解智能指针是如何与自定义删除程序一起工作的。因此,我自己编写了模拟std::uniqe_ptr
工作方式的代码。事实上,我还考虑将deleters模板函数更改为模板函数类,并将其专门用于动态数组。不管怎样,这就是我尝试过的:
template <typename T>
void Free(T* p)
{
std::cout << "Free(T*): Freeing memory of a dynamic object...n";
delete p;
}
template <typename T>
void Del_It(T* p)
{
std::cout << "Del_It(T*): freeing memory of a dynamic object...n";
delete p;
}
template <typename T, typename Deleter=void(*)(T*)>
class Uniptr
{
public:
Uniptr(T* = nullptr, Deleter = Free<T>);
virtual ~Uniptr();
private:
T* ptr_{nullptr};
Deleter delPtr_{nullptr};
};
template <typename T, typename Deleter>
Uniptr<T, Deleter>::Uniptr(T* p, Deleter d) :
ptr_(p),
delPtr_(d)
{
}
template <typename T, typename Deleter>
Uniptr<T, Deleter>::~Uniptr()
{
delPtr_(ptr_);
delPtr_ = nullptr;
}
int main()
{
Uniptr<int, void(*)(int*)> upi(new int(9), Del_It<int>);
std::cout << "ndonen";
}
- 看起来效果不错,但我需要你的建议、提示。。。谢谢
老实说,自定义deleter可以是一切。让我们弄脏我们的手,
int main()
{
auto f = [](FILE* f){std::fclose(f); std::cout<<"I am closing filen";};
std::unique_ptr<FILE,decltype(f)>fptr{std::fopen("test.txt","w"), f};
}
我们在这里做了什么?我们已经通过unique_ptr
在C中封装了文件处理。我们得到了什么?如果操作后忘记关闭文件,我们确保它会自动关闭。
所以,不要认为自定义删除程序只能用来删除指针。我可以指定用于任何应用程序,如套接字、文件等。
请检查unique_ptr
代码取自文件包装
当唯一指针被破坏时,自定义删除程序可以用来执行一些自定义清理操作。在您的情况下,除了删除指针之外,您没有做任何事情。因此,您没有执行任何自定义清理。另外,还有两个函数Free
和Del_It
,它们做同样的事情。如果Del_It
用于动态分配的数组,那么它应该执行delete [] p
。
假设您使用的是专门要求您调用释放资源的release()
函数的遗留代码:
class LegacyClass
{
...
void release() {...}
~LegacyClass() {...}
};
您不能更改遗留代码(甚至可能在共享库中(,但必须调用release()
函数。因此,您可以定义一个自定义的deleter来实现这一点:
struct Deleter
{
void operator()(LegacyClass *ptr) const
{
if (ptr)
{
ptr->release();
delete ptr;
}
}
};
通过一个唯一的指针,deleter实际上是类型的一部分:
unique_ptr<T, Deleter>
但是对于共享指针,自定义删除器不是该类型的一部分;它被传递到构造函数中。自定义删除程序可以定义为:
- 函子
- 函数指针
- λ
std::function
*
*(这个可以膨胀到你唯一指针的大小(