unique_ptr 是一种定义在中的智能指针。
1:unique_ptr 对象不能进行赋值操作和移动操作。
2:unique是独特的,唯一的意思,因此表示它独占一个对象。
3:unique_ptr和share_ptr类型有很大的不同,share_ptr允许多个指针指向同一个对象,而unique_ptr在某一时刻只能有一个指针指向该对象。两个unique不能指向同一个对象。
4.unique_ptr对象中保存指向某个对象的指针,当它本身被删除或者离开其作用域就会被自动释放其指向对选哪个所占有的资源。
//将拷贝构造函数删除
my_unique_ptr(const my_unique_ptr&) = delete;
//将赋值语句删除
my_unique_ptr &operator=(const my_unique_ptr&) = delete
int main()
{
std::unique_ptr<Object> pobja(new Object(10));
//std::unique_ptr
std::unique_ptr<Object> pobjb;
//pobjc = pobja;//赋值语句被删掉了
// pobjc = fun();//调用赋值语句,也不行
}
std::unique_ptr<Object> pobjc(std::move(pobja));
int main()
{
std::unique_ptr<Object> pobja(new Object(10));
std::unique_ptr<Object> pobjc(std::move(pobja));
pobjb = std::move(pobja);
//底层 std::(unique_ptr
}
my_unique_ptr(my_unique_ptr &&p)
{
_ptr = p._Ptr;
p._Ptr = NULL;
}
实现移动赋值:
my_unique_ptr& operator=(my_unique_ptr&& p)
{
if (this == *p) retun* this;
delete _Ptr;
_Ptr = p._Ptr
p.Ptr = NULL;
return *this;
}
template<class T,class D>
class my_unique_ptr
{
my_unique_ptr() { cout << "T,D" << endl; }
};
template<class T, class D>
class my_unique_ptr<T*,D*>
{
my_unique_ptr() { cout << "T*,D*" << endl; }
};
template<class T, class D>
class my_unique_ptr<const T*, const D*>
{
my_unique_ptr() { cout << "const T*,const D*" << endl; }
};
template<>
class my_unique_ptr<const char*, const char*>
{
my_unique_ptr() { cout << "const char*, const char*" << endl; }
};
int main()
{
my_unique_ptr<int, int>a;
my_unique_ptr<int*, int*> b;
my_unique_ptr<const int*, const int*> c;
my_unique_ptr<const char*, const char*> d;
}
std::unique_ptr<Object> obja(new Object(10));//执行的是自己自带的delete
std::unique_ptr<Object[]> objb(new Object[10]);//执行的是自己自带的delete[]
因为它定义了两个类模板,一个泛化版本和一个部分特化版本,如下:
template<class T,class D>
class my_unique_ptr
{
public:
my_unique_ptr() { cout << "T,D" << endl; }
};
template<class T, class D>
class my_unique_ptr<T[],D>
{
public:
my_unique_ptr() { cout << "T[],D" << endl; }
};
struct delete_Object
{
void operator()(Object* op)
{
if (op == NULL) return;
delete op;
}
};
struct delete_arr_Object
{
void operator()(Object* op)
{
if (op == NULL) return;
delete[] op;
}
};
int main()
{
std::unique_ptr<Object, delete_Object> objc(new Object(10));//执行的是设计的delete
std::unique_ptr<Object[], delete_arr_Object> objd(new Object[10]);
}
从这个方面我们就可以看出指针指针带来巨大的灵活性,我们还可以用它来操作文件:
比如:
int main()
{
std::unique_ptr<FILE, delete_file> objd(fopen("tulun.txt","w"));
}
struct delete_file
{
void operator()(FILE *fp)
{
if (fp == NULL) return;
fclose(fp);
}
};
class my_unique_ptr
{
private:
T* _Ptr;
public:
my_unique_ptr() { cout << "T,D" << endl; }
operator bool()()const{ return _Ptr != NULL; }
};
int main()
{
if (!pfile)
{
cout << "file open err" << endl;
}
}
如下:传统写法,当接下来的代码由于抛出异常或提前退出,就会没有执行delete操作。
void func()
{
int *p = new int(5);
//....提前退出,抛出异常
delete p ;
}
解决办法:使用unique_ptr来动态管理内存,直接unique_ptr创建成功,其析构函数就会被调用,确保动态资源释放。
void func()
{
std::unique_ptr<int> p(new int(5));
}
unique_ptr<int> func(int x)
{
unique_ptr<int> p(new int(x));//自动将pdelete
return p;
}
int main()
{
int a = 5;
unique_ptr<int> ret = func(a);//自动将ret,delete
cout << *ret << endl;
//函数结束自动释放new的资源
}
int main()
{
vector<unique_ptr<int> >vec;
unique_ptr<int> p(new int(5));
vec.push_back(std::move(p));//使用移动构造,移动赋值
}
int main()
{
unique_ptr<int[]> p(new int[5]{ 1,2,3,4,5 });
p[0] = 0;
}