文章目录
为什么需要智能指针
程序使用动态内存出于以下三种原因之一:
- 程序不知道自己需要使用多少对象
- 程序不知道所需对象的准确类型
- 程序需要在多个对象间共享数据
而在C++中动态内存的管理是通过一对运算符来完成的,即new和delete,但是动态内存的使用很容易产生以下问题:
-
忘记delete内存,导致内存泄露问题,而且这种问题很难排查,往往出现在程序运行阶段而不是编译阶段。
-
使用已释放的对象。
通过释放内存后,将指针置为空,有时可以检测出这种错误
-
同一块内存被释放两次。当两个指针指向相同的动态分配对象时,如果其中一个指针进行了delete操作,对象的内存就被归还给自由空间了,如果我们随后又delete第二个指针,自由空间就可能被破坏。

所以为了使开发人员能够更容易更安全的使用动态内存,就需要智能指针,智能指针的使用类似于指针,最主要的区别是它负责自动释放所指向的对象,目前有3种智能指针,分别是: -
shared_ptr:允许多个指针指向同一个对象 -
unique_ptr:独占所指向的对象 -
weak_ptr:弱引用,指向shared_ptr所管理的对象
STL一共提供了四种智能指针:auto_ptr、unique_ptr、shared_ptr和weak_ptr
auto_ptr功能类似于unique_ptr,但是其在C++11中已经废弃,被unique_ptr替代,原因是auto_ptr不够安全,且支持拷贝和赋值,如p2= p1,p2会接管p1原来的内存管理权,p1会变为空指针,如果p2原来不为空,则它会释放原来的资源,基于这个原因,应该避免将auto_ptr放到容器中,因为算法对容器操作时,很难避免STL内部对容器实现了赋值传递操作,这样会使容器中很多元素被置为NULL。
在C++17中auto_ptr已被废除。
unique_ptr
一个unique_ptr拥有它所指向的对象。某个时刻只能有一个unique_ptr指向一个给定对象。当unique_ptr被销毁时,它指向的对象也被销毁。
由于unique_ptr
独占的特点,所以unique_ptr不支持普通的拷贝或者赋值操作(拷贝或赋值一个将要被销毁的unique_ptr例外,比如函数返回一个unique_ptr),定义一个unique_ptr时,需要将其绑定到一个new返回的指针上,且也必须使用直接初始化方式例如:unique_ptrp(new int(10))
unique_ptr常用操作
-
u.release():u放弃对指针的控制权,返回内置指针(即new出来的指针),并将u置为空class A { public: ~A() { cout << "~A()" << endl; } }; int main() { unique_ptr<A>p1(new A); //错误:release函数只是将p1置为空,并不会释放其指向的内存。而运行后并没有任何输出,说明没有调用A的析构函数,也说明release函数不会释放其指向的内存。 p1.release(); return 0; }注意:该操作通常用来初始化另一个智能指针,如果我们不用另一个智能指针保存其返回的指针,我们的程序就要负责资源的释放
-
u.reset():释放u指向的对象 -
u.reset(q):令u指向q,q必须是内置指针;
通过release或reset将指针的所有权从一个(非const)unique_ptr转移给另一个unique_ptr;
int main()
{
unique_ptr<int>p1(new int(10));
unique_ptr<int>p2(p1.release()); //release将p1置空,并指针的控制权交给p2
p1.get() ? (cout << "p1的值为:" << *p1.get() << endl) : (cout << "p1为空指针" << endl);
p2.get() ? (cout << "p2的值为:" << *p2.get() << endl) : (cout << "p2为空指针" << endl);
unique_ptr<int>p3(new int(20));
p2.reset(p3.release());//将所有权从p3转交给p2,并释放原先p2指向的对象
p2.get() ? (cout << "p2的值为:" << *p2.get() << endl) : (cout << "p2为空指针" << endl);
p3.get() ? (cout << "p3的值为:" << *p3.get(</
本文介绍了C++中的智能指针,包括unique_ptr、shared_ptr和weak_ptr的用途和操作。unique_ptr独占对象所有权,不支持多重共享;shared_ptr允许多个指针共享对象,通过引用计数管理内存,可能导致循环引用;weak_ptr是弱引用,用于解决shared_ptr的循环引用问题。文章讨论了各种智能指针的常见操作和使用注意事项。
最低0.47元/天 解锁文章
3万+

被折叠的 条评论
为什么被折叠?



