C/C++ C++11智能指针

在使用基本指针类型时,因为要手动释放指针指向的内存,常常容易造成内存泄漏,特别是异常分支很多的情况下。而智能指针类型就是将基本指针类型封装成模板类,以便更好地管理内存。

智能指针都包含一个explicit构造函数,因此基本指针类型不能隐式转换成智能指针,需要显式调用。

shared_ptr<double> sp_d;
double *p_d = new double;
sp_d = p_d; // 错误,隐式转换。
sp_d = shared_ptr<double>(p_d); // 正确,显式转换。
shared_ptr<double> sp_d = p_d; // 错误,隐式转换。
shared_ptr<double> sp_d(p_d); // 正确,显式转换。

1、auto_ptr

1)由C++98提出,C++11中已经弃用。

std::auto_ptr<int> sp_i1(new int);
*sp_i1 = 10;
std::auto_ptr<int> sp_i2 = sp_i1; // 所有权移交给sp_i2,sp_i1变成空指针
std::cout << *sp_i1 << std::endl; // 运行崩溃

2、unique_ptr

std::unique_ptr<int> sp_i1(new int);
*sp_i1 = 10;
// 编译报错:Call to implicitly-deleted copy constructor of ‘std::unique_ptr<int>‘
// 即unique_ptr不提供拷贝构造函数unique_ptr(const unique_ptr &) = delete;
// 以及赋值运算符unique_ptr& operator=(const unique_ptr &) = delete;
std::unique_ptr<int> sp_i2 = sp_i1;
std::cout << *sp_i1 << std::endl;
// unique_ptr提供移动构造函数unique_ptr(unique_ptr &&) noexcept;
// 以及移动赋值运算符unique_ptr& operator=(unique_ptr &&) noexcept; 因为右值之后不会再用到// 和auto_ptr都是所有权移交,但是unique_ptr更优。
std::unique_ptr<int> sp_i2 = std::unique_ptr<int>(new int);
std::unique_ptr<int> sp_i1(new int);
*sp_i1 = 10;
std::unique_ptr<int> sp_i2 = std::move(sp_i1);
std::cout << *sp_i2 << std::endl;
std::cout << *sp_i1 << std::endl; // 运行崩溃,所有权已经移交给sp_i2,sp_i1变成空指针了,可以重新赋值

3、shared_ptr

shared_ptr使用引用计数技术来管理内存(正如Objective-C中的内存管理),引用计数为0,对象被析构。

std::shared_ptr<int> sp_i1(new int(100)); // sp_i1指向int(100),int(100)的引用计数为1。
std::shared_ptr<int> sp_i2 = sp_i1; // sp_i2和sp_i1同时指向int(100),int(100)的引用计数变为2。
sp_i1.reset(new int(200)); // sp_i1指向int(200),int(100)的引用计数变为1。
sp_i2.reset(); // int(100)的引用计数变为0,被析构。

4、weak_ptr

正如Objective-C会出现循环引用,导致内存无法释放,shared_ptr也有这个问题。weak_ptr可以解决这个问题,只会指向对象,对象的计数不会加1。

参考链接:

http://www.cplusplus.com/reference/memory/shared_ptr/

原文地址:https://www.cnblogs.com/yangwenhuan/p/10635102.html

时间: 2024-10-03 11:12:10

C/C++ C++11智能指针的相关文章

c++11 智能指针 unique_ptr、shared_ptr与weak_ptr

c++11 智能指针 unique_ptr.shared_ptr与weak_ptr C++11中有unique_ptr.shared_ptr与weak_ptr等智能指针(smart pointer),定义在<memory>中. 可以对动态资源进行管理,保证任何情况下,已构造的对象最终会销毁,即它的析构函数最终会被调用. unique_ptr unique_ptr持有对对象的独有权,同一时刻只能有一个unique_ptr指向给定对象(通过禁止拷贝语义.只有移动语义来实现). unique_ptr

详解C++11智能指针

前言 C++里面的四个智能指针: auto_ptr, unique_ptr,shared_ptr, weak_ptr 其中后三个是C++11支持,并且第一个已经被C++11弃用. C++11智能指针介绍 智能指针主要用于管理在堆上分配的内存,它将普通的指针封装为一个栈对象.当栈对象的生存周期结束后,会在析构函数中释放掉申请的内存,从而防止内存泄漏.C++ 11中最常用的智能指针类型为shared_ptr,它采用引用计数的方法,记录当前内存资源被多少个智能指针引用.该引用计数的内存在堆上分配.当新

C++11智能指针

C成也指针,败也指针.确实,指针给程序员提供了很多便利和灵活性,但是不当的指针使用也会造成很多问题. Java和C#避免了指针(虽然C#中也能使用指针,但是估计很少有人这样做),其垃圾回收机制,给程序员减轻很多管理内存的负担. 为了带来指针更好的使用体验,C++中引入了智能指针的概念,其实质就是将指针的一些操作封装成类,程序员通过使用熟悉的指针运算符(-> 和 *)访问封装指针,该指针类通过运算符重载返回封装的原始指针. C++ 智能指针思路类似于C#等语言中创建对象的过程:创建对象后让系统负责

c++11 智能指针

如果在程序中使用new从堆(自由存储区)分配内存,等到不需要时, 应使用delete将其释放.c++引入了智能指针auto_ptr, 以帮助自动完成这个过程. c++11摒弃了auto_ptr,并新增了三种智能指针:unique_ptr, shared_ptr, weak_ptr. 一. auto_ptr, unique_ptr , shared_ptr 头文件:  #include <memory> 用法:  auto_ptr<double>  A(new double); un

一次测试测试(C++11)智能指针引用的崩溃结论

项目中用到了智能指针,但是要在智能指针指向的类中获取此类的shared_ptr指针传给其引用的类,结果出现了问题, 测试代码如下: (包括错误解释) 1 //测试 shared_ptr weak_ptr map<string,shared_ptr> 2 #include <stdio.h> //pinrtf ... 3 #include <string> //string ... 4 #include <map> 5 #include <memory&

C++ 11智能指针之shared_ptr

 shared_ptr是一个引用计数智能指针,用于共享对象的所有权.它可以从一个裸指针.另一个shared_ptr.一个auto_ptr.或者一个weak_ptr构造.还可以传递第二个参数给shared_ptr的构造函数,它被称为删除器(deleter).删除器用于处理共享资源的释放,这对于管理那些不是用new分配也不是用delete释放的资源时非常有用.shared_ptr被创建后,就可以像普通指针一样使用了,除了一点,它不能被显式地删除.shared_ptr的比较重要的接口如下: tem

C++11 智能指针unique_ptr使用 -- 以排序二叉树为例

用智能指针可以简化内存管理.以树为例,如果用普通指针,通常是在插入新节点时用new,在析构函数中调用delete:但有了unique_ptr类型的智能指针,就不需要在析构函数中delete了,因为当unique_ptr类型的指针P生命结束时(比如对于局部变量,程序执行到局部变量的作用域范围之外),P会自动delete它拥有的资源(指针指向的空间).对于shared_ptr,情况更加复杂一些,shared_ptr会维护一个use count,即有多少个指针共享这一资源,当use count为0时,

C++11智能指针:unique_ptr

unique_ptr 1.概念 unique_ptr形如其名,与所指对象的内存紧密地绑定,不能与其他的unique_ptr类型的指针对象共享所指向对象的内存. 在cplusplus.com中,unique_ptr声明如下: // non-specialized template <class T, class D = default_delete<T>> class unique_ptr; // array specialization template <class T,

C++11智能指针和引用

最近在学习课程的时候发现一个很困惑的问题,上代码 class DataHeader; class LoginResult:public DataHeader; typedef std::shared_ptr<DataHeader> DataHeaerPtr; //原型 void addSendTask(ClientSocketPtr& pClient, DataHeaderPtr& header) //未报错调用 DataHeaderPtr ret = std::make_sh