内存控制这一大毒瘤,几乎一直伴随着C/C++工程师。随着计算机技术的发展,在boost准标准库的推动下,C++11终于将unique_ptr、shared_ptr、weak_ptr这几类智能指针纳入C++中。当然,在这之前还有一种auto_ptr智能指针,不过由于它的设计存在较大问题(比如:auto_ptr与STL不兼容),现阶段已经很少能看到它的出现了。
感谢@毛毛是我的小可爱 在评论中指出“ 标题说的还是C++14,文章开头就跑出C++11。请严谨一点!”。
这里说明一下,(1)上文中提到C++11
出现了智能指针unique_ptr、shared_ptr、weak_ptr,(2)但是文中的代码示例使用了make_unique()
和std::move()
,这些为C++14
中的内容。
智能指针实质是一个对象,行为表现的却像一个指针。
shared_ptr和unique_ptr之间的区别在于:shared_ptr是引用计数的智能指针,而unique_ptr不是。这意味着,可以有多个shared_ptr实例指向同一块动态分配的内存,当最后一个shared_ptr离开作用域时,才会释放这块内存。shared_ptr也是线程安全的。 另一方面,unique_ptr意味着所有权。单个unique_ptr离开作用域时,会立即释放底层内存。
2018-2-28更新 :感谢@奔跑的哇牛 在留言中说到shared_ptr
本身不是线程安全的。是的,shared_ptr
本身不是线程安全的。陈硕的书中也明确提到了,shared_ptr
的计数功能是原子的,但对象的读写不是原子的。c++
标准也只是保证的是weak_ptr
的lock()
指针提升是线程安全的。所以,要实现线程安全,可能需要weak_ptr
与shared_ptr
配合使用,详见陈硕的多线程书籍。
也可以参考:http://www.pandademo.com/2017/08/thread-safety-of-shared_ptr-and-weak_ptr/
默认的智能指针应该是unique_ptr。只有需要共享资源时,才使用shared_ptr。
这两个智能指针都需要包含<memory>
头文件。
在开始本文之前,首先给出一个类。因为下文中,为了演示智能指针的使用方式,在较多时候都有用到这个类demo。
#include <memory>
#include <utility> //std::move()
class demo {
public:
demo() : uptr(std::make_unique<int[]>(10)){
printf("demo\n");
for (int i = 0; i < 10; ++i){
uptr[i] = i;
}
}
~demo(){
printf("~demo\n");