C++11的智能指针小结

(1.1)指针的小介绍

int b = 9;

int *a = &b;

cout<< "a="<<a << endl;  1

cout<< "*a=" << *a << endl;2

cout<< "&a=" << &a << endl;3

cout<< "b:" << b << endl;4

cout<< "&b" << &b << endl;  5



1和5完全一样,说明a就是a被写入的值,被写入了b的地址,所以拿了b的地址(&b)就和a一样了,&a就是a本身的地址



     

  (1.2)智能指针的介绍

     #include<memory>

a)

裸指针: 直接用new返回的指针

b)智能指针:对裸指针进行了包装的指针 ,优点:能够自动释放所指向的对象内存



C++标准库有四种智能指针:auto_ptr(C++98已有)    unique_ptr 

shared_ptr weak_ptr(后三个C++11)

                                        目前auto_ptr已经完全被unique_ptr取代了   已经被委员会反对使用了

帮助我们进行动态分配的生命周期管理,能够有效防止内存泄漏





shared_ptr

共享式指针 ,多个指针指向同一个对象,最后一个指针被销毁时,内存被释放

weak_ptr

是辅助shared_ptr的

unique_ptr

独占式指针,同一时间内,只有一个指针指向一个对象 所有权还是可以转移的

shared_ptr

最后一个shared_ptr在什么情况下才能释放该对象呢?

a)这个 shared_ptr 被析构的时候

b)这个shared_ptr 指向其他对象时

格式: shared_ptr<指向的类型>智能指针名



  (1.3)shared_ptr智能指针的初始化

1、

shared_ptrp_a(new int(100));//p_a指向一个值为100的数据

        这是显式类型转换

shared_ptrp_b= new int(200);//;智能指针是显示类型装换,这个等号是隐式类型装换,必须直接初始化使用,这样写就是不行的

2、

shared_ptr make(int value)

{
return shared_ptr(new int(value));//必须这样返回
}

shared_ptr<int>p_3 = make(200);这样写也可以

3、

//可以使用裸指针初始化智能指针,但是不要穿插使用,就是不要再使用裸指针

int *p = new int(300);

shared_ptr<int>p_4(p);

4、 shared_ptrp_4_4;//初始化一个智能指针,但是指向为空(nullptr)

5、

//make_shared函数   标准库里的函数模板,安全,高效地使用shared_ptr 

//它能够在动态内存中分配并初始化一个对象,然后返回指向该对象的shared_ptr 

shared_ptr<int>p_5 =make_shared<int>(100);//与new有一点类似,但返回智能指针的类型

shared_ptr<string>p_6 =make_shared<string>(5,'q');



shared_ptr<int >p_7=make_shared<int>();//值初始化,为0

p_7= make_shared<int>(700);//p_7指向一个新内存, 它先释放刚才指向的内存,再指向新的内存

(1.4)shared_ptr函数相关

shared_ptr<int> myfunc(shared_ptr<int>&temp)

{
return temp;
}

(1.5)shared_ptr的引用计数

    共享式,引用计数,每一个shared_ptr的拷贝都指向相同的内存,只有最后一个指向该对象的shared_ptr不需要指向的时候,这个shared_ptr才会析构所有对象

  (1.5.1)引用计数的增加


每一个shared_ptr都会记录多少个其他shared_ptr指向相同的对象

auto p6 =

make_shared(100);//目前只有p6一个引用者指向100

auto p7(p6);//智能指针的初始化,p7和p6指向了相同的对象,此对象目前有两个引用者

这个情况下,所有指向该对象的shared_ptr的引用计数增加一   [2 strong ref]

(1.5.2)在下面几种情况下,引用计数会增加

a)比如上面一样,用p6初始化p7

b)把智能指针当初实参往函数里传递

myfunc(p7);//如果就直接传递,就变成3,引用传递,就还是2

c)作为函数的返回值

auto p8 = myfunc(p7);

myfunc(p8);//如果没有接的话,就当场析构掉,就不会增加

(1.5.3)引用计数减少

//a)给shared_ptr赋新值

p8= make_shared<int>(200);//p8指向新对象,原计数变成2

p7= make_shared<int>(300);//p7指向新对象,原计数变成1

p6= make_shared<int>(400);//p6指向新对象, 原对象被释放

                //可以通过查看内存来观察,注:变红就因为被释放了



//b)局部的shared_ptr离开其作用域

myfunc(p6);//进入时为3个,但是栈空间被销毁之后,就是两个了

(1.6)shared_ptr指针的常用操作

  (1.6.1)use_count()返回多少个智能指针指向该对象,主要用于调试目的

shared_ptr<int>myp(new int(100));

cout<< myp.use_count() << endl;//返回个数

  (1.6.2)unique()  是否该智能指针是否独占该对象,如果是的话就返回ture,不是的话就返回否

shared_ptr<int>myp3(new int(200));

if (myp3.unique())

{

    cout<< "是" << endl;

}

else

{

    cout<< "否" << endl;

}

(1.6.3)reset()
恢复或者复位的意思

reset()不带参数时,

若pi是唯一指向该对象的指针,那么释放pi指向的对象,并将pi置空

若pi不是唯一指向该对象的指针,那么不释放pi锁指向的对象,但指向该对象的引用计数会减少,同时将pi置空

shared_ptrpi(new int(230));

pi.reset();

if (pi==nullptr)

{

   cout<< "pi被置空" << endl;

}

else

{

    cout<< "pi没被置空" << endl;

}

reset()带参数时,(一般是一个new出来的指针)时

若pi是唯一指向该对象的指针,则释放pi指向的对象,让pi指向新对象

若pi不是唯一指向该对象的指针,则不释放pi指向的对象,但是指向该对象的引用计数会减少

1,同时让pi指向新对象;

shared_ptr<int>pi3(new int(1));

pi3.reset(new int(2));//查看内存即可了解



//空指针也可以用它来初始化

shared_ptr<int>p4;

p4.reset(new int(120));

(1.6.4)解引用,获取p4指向的对象

cout << p4 << endl;

cout << *p4 << endl;

(1.6.5)swap()交换两个智能指针所指向的对象

shared_ptrsw(new string(“hello”));

shared_ptr<string>ss(new string("myword"));

sw.swap(ss);

cout<< *sw << endl;

cout<< *ss << endl;

//或者这样写

swap(ss,sw);

(1.6.6)=nullptr

将所指向的对象引用计数减一,若引用计数为0,则释放智能指针所指向的对象

将智能指针置空


shared_ptr<string>nu(new string("hi"));

shared_ptr<string>nl(nu);

nu= nullptr;

(1.6.7)智能指针名字作为判断条件
shared_ptrpan(new int(21));
if (pan)
{
cout<< “不为空” << endl;
}
else
{
cout<< “为空” << endl;
}

(1.6.8)指定删除器以及数组问题

(1.6.9)shared_ptr的注意事项

void proc(shared_ptrp)
{

return;

}
int *d = new int(12);

    proc(d);是不行的,语法错误,int*d不能转换成shared_ptr,要临时转换

    proc(shared_ptr<int>(d));//如果这样写了之后,就不要再使用裸指针了,因为它的生命周期交给了智能指针,



    不能使用裸指针初始化多个内存,

    int *q = new int(12);

    shared_ptr<int>q_1(q);//它们两个都是只有一个强引用,说明它们没有汇通,程序结束后会delete两次该内存

    shared_ptr<int>q_2(q);

慎用get()返回的裸指针

    (有些接口只能使用裸指针)

    get返回的裸指针不能自己delete



    shared_ptr<int>dde(new int(12));

    int *q_11  =dde.get();

    delete q_11;

不能把其他智能指针绑定到get()返回的裸指针上

shared_ptrbangding(q_11);//也是不会汇通,容易delete两次

永远不能用get()得到的裸指针初始化或赋值

//(3.2)移动语义

shared_ptrv_1(new int(11));

shared_ptrv_2(move(v_1));//移动后v_1就为空

(2.7)unique_ptr概述

独占式的概念(专属所有权)同一时刻,只能有一个unique_ptr指针指向该对象(这块内存)

当这个unique_ptr被销毁时,这个指向的内存也会被销毁

     unique_ptr<对象类型>变量名

(2.8)unique_ptr常规初始化

unique_ptr<int>u_1;
if (u_1 == nullptr)
{
    cout<< "这个内存还没有初始化" << endl;
}
unique_ptr<int>u_2(new int(12));

//(1.2)make_unique函数  

C++14的

unique_ptr<int>u_3 =make_unique<int>(123);

//auto u_4(u_3);不能赋值啦   不支持拷贝操作

auto u_4(move(u_3));//但是移动可以

(1.9)relase( )

放弃对指针的控制权(切断了智能指针与其所指向的对象的联系)

//返回裸指针,并将裸指针置空

int *a = u_4.release();

cout<< *a << endl;

        //或者用它来初始化

unique_ptr<int>u_5 =

make_unique(123);

auto u_6(u_5.release());  

(1.10)reset()

       //(2.3)reset 不带参数就置空,带参数就指向新对象,原来的置空



auto p_7 =make_unique<int>(11);

auto p_8 =make_unique<int>(111);

p_7.reset(p_8.release());//不会内存泄漏,可以去MFC尝试

(1.11)=nullptr

释放智能指针所指向的对象,并将智能指针置空

p_7= nullptr;

(1.12)指向一个数组

unique_ptr<int[]>ptrarr(new int[10]);//不需要自己写删除器

ptrarr[0] = 11;

ptrarr[1] = 22;

ptrarr[2] = 23;
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值