智能指针详解

什么是智能指针?

智能指针其实和C++内置的指针行为十分相像,只不过它们所指向的对象无需我们主动进行内存释放,而是由它们在合适的时机释放所指向对象占用的内存空间,此即"智能"之处

智能指针有什么特殊功效?

首先,智能指针在遇到异常时特别有用,因为它们能确保正确销毁动态分配的对象,所以才叫智能指针啦!

其次,它们还可用于跟踪由多个所有者共享的动态分配对象!

其它功效,自己多多参悟吧!

几种常见的智能指针

一、scoped_ptr

见名知义,scoped_ptr是仅作用在某一作用域内的智能指针,离开作用域,它指向的对象将自动析构,因此也被称为作用域智能指针。由于scoped_ptr很简单,每个操作都与内置指针一样快,而且空间开销和内置指针相差无几。

scoped_ptr指向动态分配的对象(动态分配的对象用C++的new表达式分配)。指向对象被确保删除,无论是在scoped_ptr的析构函数内,还是显式调用scoped_ptr的reset函数。

scoped_ptr是满足简单需求的解决方案,不能共享所有权,它仅在当前范围内保留所有权。scoped_ptr是不可复制的,因为在类内部将 拷贝构造函数 和 =运算符重载 定义为 私有的。所以对于不应复制的指针,它比共享指针(shared_ptr)更安全

这里,如果一个对象交由多个scoped_ptr管理有安全漏洞吗? 看下面一段代码

1 int main()
2 {   
3     {
4         Book * book = new Book();
5         scoped_ptr<Book> myBook(book);
6         scoped_ptr<Book> myBook1(book);
7     }
8     return 0;
9 }

虽然编译能通过,但是运行必然报错,book对象北析构了两次啊竟然!

其次,一定不能在C++标准库容器中使用scoped_ptr!参看下面的代码

1 int main()
2 {   
3     {
4         scoped_ptr<Book> myBook(new Book("「1984」"));
5         vector<boost::scoped_ptr<Book>> vecScoped;
6         //vecScoped.push_back(myBook);   // Error: push_back操作内部调用了scoped_ptr的=运算符重载函数
7     }
8     return 0;
9 }

为什么要使用scoped_ptr?

使用scoped_ptr而不是std::auto_ptr或std::unique_ptri的主要原因是让读者知道你打算仅应用于当前作用域,不打算转移所有权。

使用scoped_ptr是防止以后维护代码的程序员添加返回auto_ptr的函数来转移所有权,因为程序员看到了auto_ptr会假定所有权可以安全地转移。可以想想bool和int,我们都知道bool通常就是一个int值,但是通过编写bool而不是int,可以告诉读者你的真实意图是什么。这个与scoped_ptr使用动机是相同的,就是让读者理解你的意图而已。

scoped_array

实际上是scoped_ptr的数组形式,应用场景和注意事项与scoped_ptr类似,在此不在赘述。

二、shared_ptr

多个 shared_ptr 对象可共同托管一个指针 p,当所有托管 p 的 shared_ptr 对象都解除了对其托管时,就会delete p。

先上一个例子热下身

shared_ptr<X> p1( new X );

shared_ptr<void> p2( new int(5) );

上面两行代码中,shared_ptr将删除在构造时传递的确切指针,包括其原始类型,而不考虑模板参数。当p2被销毁或重置时,它将调用传递给构造函数的原始int*上的delete,即使p2本身是shared-ptr<void>类型并存储void*类型的指针

其次,shared_ptr满足C++标准库可复制、可赋值等需求,因此可用于标准的库容器中。提供比较运算符,以便shared_ptr与标准库的关联容器一起工作。

线程安全问题

shared_ptr提供与内置类型相同级别的线程安全性。也就是说多个线程同时读是安全的,多个线程同时读写或者同时写是不安全的。

发布了94 篇原创文章 · 获赞 31 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/gaoxueyi551/article/details/102646424
今日推荐