共享指针 shared_ptr

  1. /*********** Shared_ptr ***********/
  2. // 为什么要使用智能指针,直接使用裸指针经常会出现以下情况
  3. // 1. 当指针的生命长于所指的资源:野指针
  4. // 2. 当指针的生命短于所指的资源:资源泄漏
  5. //
  6. // 智能指针: 确保指针和资源的生命周期相同
  7. class Dog {
  8. string m_name;
  9. public:
  10. void bark() { cout << "Dog " << m_name << " rules!" << endl; }
  11. Dog(string name) { cout << "Dog is created: " << name << endl; m_name = name; }
  12. Dog() { cout << "Nameless dog created." << endl; m_name = "nameless"; }
  13. ~Dog() { cout << "dog is destroyed: " << m_name << endl; }
  14. //void enter(DogHouse* h) { h->setDog(shared_from_this()); } // Dont's call shared_from_this() in constructor
  15. };
  16. class DogHouse {
  17. shared_ptr<Dog> m_pD;
  18. public:
  19. void setDog(shared_ptr<Dog> p) { m_pD = p; cout << "Dog entered house." << endl;}
  20. };
  21. int main ()
  22. {
  23. shared_ptr<Dog> pD(new Dog("Gunner"));
  24. shared_ptr<Dog> pD = make_shared<Dog>(new Dog("Gunner")); // 另一种方式,更快且更安全
  25. pD->bark(); // 重载了箭头,可以像直接操作指针一样进行操作
  26. cout << pD.use_count(); // 指示有多少shared_ptr指向对象
  27. (*pD).bark();
  28. //DogHouse h;
  29. // DogHouse* ph = new DogHouse();
  30. // ph->setDog(pD);
  31. // delete ph;
  32. //auto pD2 = make_shared<Dog>( Dog("Smokey") ); // 不要对栈上的对象使用shared_ptr
  33. // auto pD2 = make_shared<Dog>( *(new Dog("Smokey")) );
  34. // pD2->bark();
  35. //
  36. // 对象一创建就应该立马放入智能指针中,避免使用裸指针
  37. // Dog* p = new Dog(); // 不是一个好的使用方式,容易出错
  38. // shared_ptr<int> p1(p);
  39. // shared_ptr<int> p2(p); // 出错,p会被delete两次
  40. shared_ptr<Dog> pD3;
  41. pD3.reset(new Dog("Tank"));
  42. pD3.reset(); // Dog销毁。同: pD3 = nullptr;
  43. //
  44. //pD3.reset(pD.get()); // crashes返回raw point
  45. /********** 自定义Deleter ************/
  46. shared_ptr<Dog> pD4( new Dog("Victor"),
  47. [](Dog* p) {cout << "deleting a dog.\n"; delete p;}
  48. );
  49. // 默认的deleter是operator delete.
  50. //shared_ptr<Dog> pDD(new Dog[3]); // Dog[1]和Dog[2]内存泄漏
  51. shared_ptr<Dog> pDD(new Dog[3], [](Dog* p) {delete[] p;} ); // 所有3个Dog都会被delete

弱指针 weak_ptr

  1. /*********** weak_ptr *********************/
  2. // weak_ptr对所指对象没有所有权
  3. // 对象何时delete,怎么delete跟我没有关系
  4. // 所以weak_ptr不是一直有效的,需要检查有效性。
  5. class Dog {
  6. //shared_ptr<Dog> m_pFriend;
  7. weak_ptr<Dog> m_pFriend; //跟Dog* m_pFriend类似,不过提供了一层保护,没有人可以delete它。并不是永远有效的,如果weak_ptr指向的指针被delete了
  8. public:
  9. string m_name;
  10. void bark() { cout << "Dog " << m_name << " rules!" << endl; }
  11. Dog(string name) { cout << "Dog is created: " << name << endl; m_name = name; }
  12. ~Dog() { cout << "dog is destroyed: " << m_name << endl; }
  13. void makeFriend(shared_ptr<Dog> f) { m_pFriend = f; }
  14. void showFriend() { //cout << "My friend is: " << m_pFriend.lock()->m_name << endl;
  15. if (!m_pFriend.expired()) cout << "My friend is: " << m_pFriend.lock()->m_name << endl;
  16. cout << " He is owned by " << m_pFriend.use_count() << " pointers." << endl; }//lock()将其转化为shared_ptr,检查指针有效性,同时保证指针不被delete
  17. };
  18. int main () //使用共享指针的话,会资源泄漏。因为循环引用。
  19. {
  20. shared_ptr<Dog> pD(new Dog("Gunner"));
  21. shared_ptr<Dog> pD2(new Dog("Smokey"));
  22. pD->makeFriend(pD2);
  23. pD2->makeFriend(pD);
  24. pD->showFriend();
  25. }

unique_ptr

  1. /*********** unique_ptr *********************/
  2. // Unique指针:独占对象所有权,开销比shared_ptr小
  3. class Dog {
  4. //Bone* pB;
  5. unique_ptr<Bone> pB; // 防止内存泄漏,即使构造函数在new之后抛出异常
  6. public:
  7. string m_name;
  8. void bark() { cout << "Dog " << m_name << " rules!" << endl; }
  9. Dog() { pB = new Bone(); cout << "Nameless dog created." << endl; m_name = "nameless"; }
  10. Dog(string name) { cout << "Dog is created: " << name << endl; m_name = name; }
  11. ~Dog() { delete pB; cout << "dog is destroyed: " << m_name << endl; }
  12. };
  13. void test() {
  14. //Dog* pD = new Dog("Gunner");
  15. unique_ptr<Dog> pD(new Dog("Gunner"));
  16. pD->bark();
  17. /* pD做许多操作*/
  18. //Dog* p = pD.release(); //返回raw point,同时转让原对象的所有权,不会再自动delete Dog
  19. pD = nullptr; // Dog("Gunner")被销毁
  20. //pD.reset(new Dog("Smokey")); // Dog("Gunner")被销毁
  21. if (!pD) {
  22. cout << "pD is empty.\n";
  23. }
  24. //delete pD;
  25. }
  26. void f(unique_ptr<Dog> p) {
  27. p->bark();
  28. }
  29. unique_ptr<Dog> getDog() {
  30. unique_ptr<Dog> p(new Dog("Smokey"));
  31. return p; // 传值返回,会自动使用move语义
  32. }
  33. void test2() {
  34. unique_ptr<Dog> pD(new Dog("Gunner"));
  35. unique_ptr<Dog> pD2(new Dog("Smokey"));
  36. pD2 = move(pD);
  37. // 1. Smokey is destroyed
  38. // 2. pD becomes empty.
  39. // 3. pD2 owns Gunner.
  40. pD2->bark();
  41. // f(move(pD)); // "Gunner"所有权已不属于pD,在f结束后销毁
  42. // if (!pD) {
  43. // cout << "pD is empty.\n";
  44. // }
  45. //
  46. // unique_ptr<Dog> pD2 = getDog();
  47. // pD2->bark();
  48. unique_ptr<Dog[]> dogs(new Dog[3]); //参数支持数组,不需要像shared_ptr定义deleter。因为unique_ptr对数组进行了偏特化
  49. dogs[1].bark();
  50. //(*dogs).bark(); // * is not defined
  51. }
  52. void test3() {
  53. // prevent resource leak even when constructor fails
  54. }
  55. int main ()
  56. {
  57. test2();
  58. }

C++11--智能指针shared_ptr,weak_ptr,unique_ptr <memory>的更多相关文章

  1. C++11智能指针之std::unique_ptr

    C++11智能指针之std::unique_ptr   uniqut_ptr是一种对资源具有排他性拥有权的智能指针,即一个对象资源只能同时被一个unique_ptr指向. 一.初始化方式 通过new云 ...

  2. 【C++11新特性】 C++11智能指针之weak_ptr

    如题,我们今天要讲的是C++11引入的三种智能指针中的最后一个:weak_ptr.在学习weak_ptr之前最好对shared_ptr有所了解.如果你还不知道shared_ptr是何物,可以看看我的另 ...

  3. C++11——智能指针

    1. 介绍 一般一个程序在内存中可以大体划分为三部分——静态内存(局部的static对象.类static数据成员以及所有定义在函数或者类之外的变量).栈内存(保存和定义在函数或者类内部的变量)和动态内 ...

  4. 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), ...

  5. 深入学习c++--智能指针(二) weak_ptr(打破shared_ptr循环引用)

    1. 几种智能指针 1. auto_ptr: c++11中推荐不使用他(放弃) 2. shared_ptr: 拥有共享对象所有权语义的智能指针 3. unique_ptr: 拥有独有对象所有权语义的智 ...

  6. c/c++ 智能指针 shared_ptr 使用

    智能指针 shared_ptr 使用 上一篇智能指针是啥玩意,介绍了什么是智能指针. 这一篇简单说说如何使用智能指针. 一,智能指针分3类:今天只唠唠shared_ptr shared_ptr uni ...

  7. C++智能指针shared_ptr

    shared_ptr 这里有一个你在标准库中找不到的—引用数智能指针.大部分人都应当有过使用智能指针的经历,并且已经有很多关于引用数的文章.最重要的一个细节是引用数是如何被执行的—插入,意思是说你将引 ...

  8. C++11智能指针读书笔记;

    智能指针是一个类对象,而非一个指针对象. 原始指针:通过new建立的*指针 智能指针:通过智能指针关键字(unique_ptr, shared_ptr ,weak_ptr)建立的指针 它的一种通用实现 ...

  9. c/c++ 智能指针 shared_ptr 和 new结合使用

    智能指针 shared_ptr 和 new结合使用 用make_shared函数初始化shared_ptr是最推荐的,但有的时候还是需要用new关键字来初始化shared_ptr. 一,先来个表格,唠 ...

  10. 详解C++11智能指针

    前言 C++里面的四个智能指针: auto_ptr, unique_ptr,shared_ptr, weak_ptr 其中后三个是C++11支持,并且第一个已经被C++11弃用. C++11智能指针介 ...

随机推荐

  1. JavaBasic_06

    二维数组 二维数组定义格式 格式1 数据类型 变量名 = new 数据类型m; m表示这个二维数组有多少个一维数组 n表示每一个一维数组的元素个数 格式2 灵活性 数据类型 a = new 数据类型m ...

  2. Gym101485: NWERC 2015(队内第6次训练)

    A .Assigning Workstations 题意:给定N个人的工作时间和工作时长,我们可以假设有无数台工作机器,如果一台机器超过M时间未使用就会关闭,那么我们怎么安排机器的使用,使得需要开启机 ...

  3. a标签的功能

    最常见的a标签是用来做跳转链接,实际上a标签还有其他的功能,具体如下: <a href="http://www.cnblogs.com/wangzhenyu666/"> ...

  4. 《DSP using MATLAB》Problem 6.23

    代码: %% ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ %% Output In ...

  5. THML分组元素

    学习要点:     1.分组元素总汇     2.分组元素解析 一.分组元素总汇         元素名称                                 说明             ...

  6. java知识 特殊符号转换

    ■情况 想把代码中的出现  “  ’等特殊符号时,在他们的前面,转换时自动加 \    最后转换成json 决定用ObjectMapper这个类,先准备一个Map,之后,map作为一个参数,调用Obj ...

  7. java 调用process

    java调用process 有两种实现方法,一是使用Runtime类,二是使用Process类. 我在最近的项目里用的是Runtime类,接下来写下总结. 有图有真相(在网上学来一句话) packag ...

  8. AangularJS入门总结三

    (参考的资料) 1. 数据绑定的原理: (1)  $watch 队列: 在DOM中每次绑定一些东西,就会往$watch队列中插入一条$watch: 每一个绑定到了DOM上的数据都会生成一个$watch ...

  9. Collection接口中方法的使用

    Collection:集合的接口 1.Collection和ArrayList和List的关系 ArrayList      implement(实现)       List List        ...

  10. php 数组排序 按照某字段

    $arr=[     array(         'name'=>'小坏龙',         'age'=>28     ),     array(         'name'=&g ...