我们知道可通过智能指针来管理资源,我们还知道当开辟资源的方式和释放资源的方式不匹配时,是可能编译报错的。那么问题就来了!
默认情况下,智能指针使用delete释放其管理的资源,有时候,可能要修改默认使用delete释放资源的行为。但如果不是new出来的资源,如何通过智能指针管理呢?
unique_ptr的简单模拟:
template<class T>
struct default_delete
{
void operator()(T* ptr)
{
delete ptr;
}
};
template<class T, class D = default_delete<T>>
class unique_ptr
{
public:
// RAII思想
unique_ptr(T* ptr)
:_ptr(ptr)
{}
~unique_ptr()
{
if (_ptr)
{
//cout << "delete" << _ptr << endl;
//delete _ptr;
D del;
del(_ptr);
_ptr = nullptr;
}
}
// 像指针一样
T& operator*()
{
return *_ptr;
}
T* operator->()
{
return _ptr;
}
T* get()
{
return _ptr;
}
unique_ptr(const unique_ptr<T>& sp) = delete;
unique_ptr<T>& operator=(const unique_ptr<T>& sp) = delete;
private:
T* _ptr;
};
💡💡💡下面我们看一个实例:
class Date
{
public:
~Date()
{
cout << "~Date()" << endl;
}
private:
int _year = 1;
int _month = 1;
int _day = 1;
};
// unique_ptr/shared_ptr 默认释放资源用的delete
// 如何匹配申请方式去对应释放呢?
template<class T>
struct DeleteArray
{
void operator()(T* ptr)
{
cout << "delete[]" << ptr << endl;
delete[] ptr;
}
};
template<class T>
struct Free
{
void operator()(T* ptr)
{
cout << "free" << ptr << endl;
free(ptr);
}
};
struct Fclose
{
void operator()(FILE* ptr)
{
cout << "fclose" << ptr << endl;
fclose(ptr);
}
};
// 定制删除器
int main()
{
pxl::unique_ptr<Date> up1(new Date);
pxl::unique_ptr<Date, DeleteArray<Date>> up2(new Date[10]);
pxl::unique_ptr<Date, Free<Date>> up3((Date*)malloc(sizeof(Date) * 10));
pxl::unique_ptr<FILE, Fclose> up4((FILE*)fopen("Test.cpp", "r"));
//share的支持方式不一样
// 传对象
std::shared_ptr<Date> sp1(new Date[10], DeleteArray<Date>());
std::shared_ptr<Date> sp2(new Date[10], [](Date* ptr){delete[] ptr; });//lambda对象
return 0;
}
看下面两张图:
注意:unique_ptr和shared_ptr的支持方式不一样(一个是在模板参数支持,一个是在构造函数支持),unique_ptr是传模板参数,而shared_Ptr是传对象!