zoukankan      html  css  js  c++  java
  • C++11 智能指针

    前言

    • 智能指针可以对动态资源进行管理,保证任何情况下,已经构造的对象能够安全的自动销毁。说人话就是防止内存泄漏。
    • C++里面共有四个智能指针:auto_ptr、unique_ptr、shared_ptr、weak_ptr,第一个已经C++11抛弃,后三个是c++11所支持。

    auto_prt 所有权模式

    auto_ptr<string> ap1 (new string ("hello,world")); 
    auto_ptr<string> ap2;
    ap2=ap1
    //这里不会报错,ap2剥夺ap1的权限,但程序访问ap1会报错,ap1被废弃。auto_ptr缺点是:存在潜在的程序崩溃问题。
    

    unique_ptr 独占指针

    • 独占指针所指向的内存为自己独有,同一时刻只能有一个unique_ptr。指向给定的对象unique_ptr 对象不支持同类赋值和拷贝。
    
    unique_ptr<int> up1(new int(2333));
    unique_ptr<int> up2 = up1;//这里会报错,尝试引用已删除的函数。
    
    //将原来up1指向内存交由up3指向
    unique_ptr<int> up3 = std::move(up1);
    cout << *up3 << endl;
    cout << *up1 << endl;//内部已经将原来的指向设置为了nullptr但是并没有删除
    
    //如果是reset带参调用
    unique_ptr<int> up4(new int(2333));
    up4.reset(new int(9999));//将原来指向的2333删除掉重新指向9999
    cout << *up4 << endl;
    
    up4 = nullptr;//相当于up4.reset(nullptr);
    //cout << *up4 << endl;
    
    unique_ptr<int> up5(new int(777));
    int* p5 = up5.release();//将内存的控制权交给接受的指针,自己赋值为nullptr,但是没有删除
    //cout << *up5 << endl;//已经失去了对之前内存的控制
    cout << *p5 << endl;
    delete p5;//需要手动释放
    

    shared_ptr 共享指针

    • 允许多个该智能指针共享一个堆内存。通过引用计数来实现共同管理和安全释放,只有引用计数为0的时候才会删除该对象的内存,支持赋值和拷贝的
    shared_ptr<int> sp1(new int(123));
    cout << sp1.use_count() << endl;
    shared_ptr<int> sp2 = sp1;//增加了引用计数
    cout << sp2.use_count() << endl;
    cout << *sp1 << " " << *sp2 << endl;
    
    sp1.reset();//对计数进行了减1,并且sp1退出了对共享的内存的管理
    cout << sp2.use_count() << endl;//1
    cout << sp1.use_count() << endl;//0
    cout << sp2.unique() << endl;//判断当前是否为独占(是否只有一个引用对象)
    
    sp1 = sp2;
    cout << sp2.use_count() << endl;//2
    cout << sp1.use_count() << endl;//2
    //共享指针之间可以交换
    shared_ptr<int> sp3(new int(456));
    sp2.swap(sp3);//将sp2指向和sp3指向进行了交换,对应的引用计数的变化要清楚
    cout << sp1.use_count() << endl;//2
    cout << sp2.use_count() << endl;//1
    cout << sp3.use_count() << endl;//2
    shared_ptr<int> sp4 = sp2;
    //获取共享指针的原始指针
    int* p = sp2.get();
    cout << p[0] << endl;
    p[0] = 321;
    cout << *sp4 << endl;
    
    //安全的使用共享指针,推荐使用make_shared函数来进行共享指针对象的创建
    shared_ptr<int> sp5 = make_shared<int>();
    cout << *sp5 << endl;
    shared_ptr<int> sp6 = make_shared<int>(9527);
    cout << *sp6 << endl;
    shared_ptr<string> sp7 = make_shared<string>(10, '9');
    cout << *sp7 << endl;
    

    weak_ptr 弱指针

    • 主要是为了配合shared_ptr而引入的一种智能指针,只要为了解决循环引用的问题。
    • 可以从一个shared_ptr或者另一个weak_ptr对象来构造,但是它的构造和析构不会对引用计数产生实质的影响。
    • 并且没有重载*,->这样的指针操作,也就是说weak_ptr对象是没有办法当做指针直接使用的。如果要使用,可以通过lock函数获得一个shared_ptr对象来使用。
    shared_ptr<A> aa = make_shared<A>();
    shared_ptr<B> bb = make_shared<B>();
    //执行结束以后内存没有被释放,循环引用导致的
    aa->b = bb;//2
    bb->a = aa;//2
    
    //改用弱指针可以消除循环引用的弊端
    aa->wb = bb;//1
    bb->wa = aa;//1
    

    总结

    • 智能指针虽然帮忙管理内存,但是带来程序运行效率的下降。
    • 主要根据自己的需求来灵活使用。
  • 相关阅读:
    golang框架对比Revel and Beego
    Gin框架系列02:路由与参数
    用cp命令拷贝文件,源目录后带不带斜杠的区别
    Isilon Gen6的换盘步骤
    如何在同一行里执行多个linux命令?
    KB,MB,GB,TB,PB,EB,ZB,YB,BB
    Isilon的WebUI上指定跨时区时间的小问题
    用Powershell强制同步Windows主机与Internet time server的时间
    Remote Desktop突然不能用了 “This could be due to CredSSP encryption oracle remediation”
    打开KVM Console的一些注意事项
  • 原文地址:https://www.cnblogs.com/biu-we/p/13367198.html
Copyright © 2011-2022 走看看