前言
C++ 标准模板库 STL(Standard Template Library) 一共给我们提供了四种智能指针:auto_ptr、unique_ptr、shared_ptr 和 weak_ptr,其中 auto_ptr 是 C++98 提出的,C++11 已将其摒弃,并提出了 unique_ptr 替代 auto_ptr。虽然 auto_ptr 已被摒弃,但在实际项目中仍可使用,但建议使用更加安全的 unique_ptr,后文会详细叙述。shared_ptr 和 weak_ptr 则是 C+11 从准标准库 Boost 中引入的两种智能指针。此外,Boost 库还提出了 boost::scoped_ptr、boost::scoped_array、boost::intrusive_ptr 等智能指针,虽然尚未得到 C++ 标准采纳,但是在开发实践中可以使用。
一 auto_ptr
auto_ptr 同样是 STL 智能指针家族的成员之一,由 C++98 引入,定义在头文件。其功能和用法类似于 unique_ptr,由 new expression 获得对象,在 auto_ptr 对象销毁时,他所管理的对象也会自动被 delete 掉。
下面是一些成员函数及其简介
- get:得到对象类管理的对象指针
- operator*:得到管理的对象
- operator->:等价于(*class).,用于获取对象的某个成员
- release:将管理对象的指针返回并设置类内指针为null
- operator= :相当于调用release之后将返回值构造为新的类初始化左边的类,Release and copy auto_ptr
- reset:若无参数直接释放当前对象否则用参数重新设置当前值,无返回值
下面是一个小例子
#include <iostream>
#include <memory>
int main()
{
/*
get:得到对象类管理的对象指针
operator*:得到管理的对象
operator->:等价于(*class).,用于获取对象的某个成员
release:将管理对象的指针返回并设置类内指针为null
operator= :相当于调用release之后将返回值构造为新的类初始化左边的类,Release and copy auto_ptr
reset:若无参数直接释放当前对象否则用参数重新设置当前值,无返回值
*/
std::auto_ptr<int> a;
a.reset(new int);//reset:当前对象否则用参数重新设置当前值,无返回值
*a = 1;
cout << "a:" << *a << endl;// operator*:得到管理的对象
*a = 2;
std::auto_ptr<int> b;
b = a;//operator= :相当于调用release之后将返回值构造为新的类初始化左边的类,
if (a.get())//get:得到对象类管理的对象指针
{
cout << "a:" << *a << endl;
}
cout << "b:" << *b << endl;
*b = 3;
int *c = b.release();//release:将管理对象的指针返回并设置类内指针为null
if (a.get())
{
cout << "b:" << *b << endl;
}
*c = 4;
cout << "c:" << *c << endl;
std::auto_ptr<int> d;
d.reset(c);
*d = 5;
if (d.get())
{
cout << "d:" << *d << endl;
}
cout << "c:" << *c << endl;
d.reset();//reset:若无参数直接释放,无返回值
if (d.get())
{
cout << "d:" << *d << endl;
}
getchar();
return 0;
}
二.unique_ptr
unique_ptr 由 C++11 引入,旨在替代不安全的 auto_ptr。unique_ptr 是一种定义在头文件中的智能指针。它持有对对象的独有权——两个unique_ptr 不能指向一个对象,即 unique_ptr 不共享它所管理的对象。它无法复制到其他 unique_ptr,无法通过值传递到函数,也无法用于需要副本的任何标准模板库 (STL)算法。只能移动 unique_ptr,即对资源管理权限可以实现转移。这意味着,内存资源所有权可以转移到另一个 unique_ptr,并且原始 unique_ptr 不再拥有此资源。实际使用中,建议将对象限制为由一个所有者所有,因为多个所有权会使程序逻辑变得复杂。因此,当需要智能指针用于存 C++ 对象时,可使用 unique_ptr,构造 unique_ptr 时,可使用 make_unique Helper 函数。
相比于auto_ptr,其可以在编译期间合理确定智能指针对象作为右值时的合法性,只有作为临时右值才合法否则报错
unique_ptr<int> getUnique(int parm)
{
unique_ptr<int> temp(new int(parm));
return temp;
}
int main()
{
unique_ptr<int> a; //创建空智能指针
a.reset(new int); //绑定动态对象
*a = 1;
cout << "a:" << *a << endl;
*a = 2;
unique_ptr<int>b = std::move(a);//所有权转移(通过移动语义),u_s所有权转移后,变成“空指针”
if (a.get())
{
cout << "a:" << *a << endl;
}
cout << "b:" << *b << endl;
*b = 3;
unique_ptr<int> c;
c.reset(b.release());//所有权转移
if (b.get())
{
cout << "b:" << *b << endl;
}
cout << "c:" << *c << endl;
//unique_ptr<int> d = c; //编译出错,已禁止拷贝
//unique_ptr<int> d(c); //编译出错,已禁止拷贝
//unique_ptr<int> d;
//d = c;//编译出错,已禁止赋值
unique_ptr<int> d = getUnique(1);//临时正确
getchar();
return 0;
}
三 shared_ptr
明天再写