【C++】不带引用计数的智能指针
不带引用计数的指针的浅拷贝会导致重复析构同一资源。
template<typename T>
class CSmartPtr{
public:
CSmartPtr(T* ptr = nullptr)
:mptr(ptr){}
~CSmartPtr(){ delete mptr;}
// CSmartPtr(const CSmartPtr<T> &src){
// mptr = new T(*(src.mptr));
// }
T& operator*(){ return *mptr; }
T* operator->(){ return mptr; }
private:
T* mptr;
};
int main(){
/*
* 不带引用计数的智能指针
*/
CSmartPtr<int> p1(new int);
CSmartPtr<int> p2(p1); // 浅拷贝,重复析构统一资源
}
不带引用计数的智能指针是如何解决浅拷贝问题的?
auto_ptr
作用简单,退出作用域析构时直接释放其内裸指针指向的内存地址。只让最后一个拷贝的指针指向资源区。转移对象的持有权。
#include <iostream>
#include <memory>
using namespace std;
template<typename T>
class CSmartPtr{
public:
CSmartPtr(T* ptr = nullptr)
:mptr(ptr){}
~CSmartPtr(){ delete mptr;}
// CSmartPtr(const CSmartPtr<T> &src){
// mptr = new T(*(src.mptr));
// }
T& operator*(){ return *mptr; }
T* operator->(){ return mptr; }
private:
T* mptr;
};
int main(){
/*
* 不带引用计数的智能指针
* auto_ptr: C++库里面
* C++11
* scoped_ptr
* unique_ptr
*/
/*
* 怎么解决浅拷贝问题!!!
*/
// CSmartPtr<int> p1(new int);
// CSmartPtr<int> p2(p1); // 浅拷贝,重复析构统一资源
auto_ptr<int> ptr1(new int);
auto_ptr<int> ptr2(ptr1); // 将被拷贝对象的资源移走置空
*ptr2 = 20;
cout << *ptr2 << endl;
}
浅拷贝逻辑
转移对象的持有权。只让最后一个拷贝的指针指向资源区,之前的指针置空。
auto_ptr<int> ptr2(ptr1);
ptr1.release(); // 拷贝构造

不推荐使用auto_ptr
vector<auto_ptr<int>> vec1;
vec2(vec1); // 导致容器vec1中的智能指针全部置空
建议只在简单管理内存时使用
scoped_ptr
直接禁止拷贝,单独一对一管理一块内存
scoped_ptr(const scoped_ptr<T>&) = delete;
scoped_ptr<T>& operator=(const scoped_ptr<T>&) = delete;
unique_ptr
类似scoped_ptr,删除了直接的拷贝构造
unique_ptr(const unique_ptr<T>&) = delete;
unique_ptr<T>& operator=(const unique_ptr<T>&) = delete;
但是提供了与auto_ptr类似的右值的拷贝构造和赋值运算重载
unique_ptr(const unique_ptr<T> &&src)
unique_ptr<T>& operator=(unique_ptr<T> &&src)
template<typename T>
unique_ptr<T> getSmartPtr(){
unique_ptr<T> ptr(new T());
return ptr;
}
// 函数返回的对象可以作为右值赋值给ptr
unique_ptr<int> ptr = getSmartPtr<int>();
几乎与auto_ptr相同,但其资源转移过程需要显式move,减少语义上的模糊性,推荐使用。

浙公网安备 33010602011771号