C++基础::shared_ptr 编程细节(一)

C++基础::shared_ptr 编程细节(二)

C++基础::shared_ptr 编程细节(三)

智能指针是c++ 中管理资源的一种方式,用智能指针管理资源,不必担心资源泄露,将 c++ 程序员从指针和内存管理中解脱出来。

shared_ptr 的两面性

  • shared_ptr 型智能指针对象的本质是类实例;

    所以允许.+成员函数的调用方式(这里的成员函数是 shared_ptr 作为类实例所具有的成员函数),比如一个shared_ptr最为类实例的成员函数:

    • .use_count()
    • .get()
    • .reset()
    • .unique()
  • 含义上作为智能指针的一面

    所以允许->成员函数的调用方式(这里的成员函数为智能指针所维护的真实对象所具有的成员函数)。

shared_ptr 的副作用

shared_ptr:一种智能指针,本意封装原生指针(new 出来的堆对象),实现指针的类型安全,然而,见名知意,它是共享型指针,即允许多个shared_ptr“指向”同一个对象,当我们在某些情况下不需要这一看似美好的性质时,该如何处理呢。

class Item
{
private:std::string _name;float _price;
public:Item(const std::string& name, float price):_name(name), _price(price){}float getPrice() const { return _price;}void setPrice(float price) { _price = price;}Item* clone() const { return new Item(*this);}
};// 单纯为了演示的需要,并无实际的意义
class A
{
public:A(const std::shared_ptr<Item>& obj):_obj(obj){}const std::shared_ptr<Item>& get() const{ return _obj;}
private:std::shared_ptr<Item> _obj;
};int main(int, char**)
{std::shared_ptr<Item> item1(new Item("C++", 20.));A a(item1);// 此时查看item1的引用次数:std::cout << item1.use_count() << std::endl;// 2// 如果使用对象a对内部的_obj进行修改,会同步到item1中a.get()->setPrice(30.);std::cout << item1->getPrice() << std::endl;// 这时我们创建另外一个A对象A b(a);// 这时如果不对A的拷贝构造进行重载的话,b也会持有一份对item1对象的引用std::cout << item1.use_count() << std::endl;// 3return 0;
}

这就是shared_ptr共享型智能指针的便捷和局限。那么,我们该如何使用拷贝构造时,建立自己独特的副本呢?

我们需要显式地给出A的拷贝构造,避免编译器对拷贝构造的默认实现:

class A
{
...
public:A(const A& other){_obj = std::shared_ptr<Item>(other.get()->clone());}
}

所以结论是,在一个需被 shared_ptr 封装的类内部给出非常关键 clone() 函数的实现非常关键

    Obj* clone() const { return new Obj(*this); }

以 shared_ptr 类类型为容器类型的容器之间的赋值

是继续持有对象的引用,还是一份全新的拷贝;


std::shared_ptr<Item> item1(new Item("C++", 20.5));
std::shared_ptr<Item> item2(new Item("Python", 25.5));std::vector<std::shared_ptr<Item>> v1 = {item1, item2};
std::vector<std::shared_ptr<Item>> v2 = v1;// 继续持有引用
std::cout << item1.use_count() << std::endl;// 3
item1->setPrice(30.);
std::cout << v2[0]->getPrice() << std::endl;std::vector<std::shared_ptr<Item>> v3;
for (size_t i = 0; i < v1.size(); ++i)v3.push_back(std::shared_ptr<Item>(v1[i]->clone()));// 一份全新的拷贝
item2->setPrice(35.5);
std::cout << v3[1]->getPrice() << std::endl;// 25.5

C++基础::shared_ptr 编程细节(一)相关推荐

  1. C++基础::shared_ptr 编程细节(三)

    C++基础::shared_ptr 编程细节(一) C++基础::shared_ptr 编程细节(二) C++基础::shared_ptr 编程细节(三) boost::shared_ptr std: ...

  2. C++基础::shared_ptr 编程细节(二)

    C++基础::shared_ptr 编程细节(一) C++基础::shared_ptr 编程细节(二) C++基础::shared_ptr 编程细节(三) *sp 与 sp.get() sp.get( ...

  3. 嵌入式C程序基础与编程结构

    嵌入式C程序基础与编程结构 Basics of Embedded C Program and Programming Structure 嵌入式C编程是处理器在我们日常生活中遇到的每一个嵌入式系统(如 ...

  4. 非洲瓜哇JAVA布的特点_java语言的基本特性以及编程细节

    前言 java语言的学习是一个体系,所以如果想要对java的编程有一个很精通的一个掌握,它离不开很多基础的知识点,比如JVM的原理.java多线程并发编程.数据结构等等.所以我这里对我学习的java的 ...

  5. java原生的编译软件_原生态Java 程序员容易忽视的编程细节

    Java是Java程序设计语言和Java平台的总称,要想学好一门语言,打好基础最关键的,学习一种新的编程语言比学习新的口头语言要容易得多.然而,在这两种学习过程中,都要付出额外的努力去学习不带口音地说 ...

  6. 如何零基础自学编程能找到工作

    现在很多年轻人喜欢计算机,喜欢软件开发,想从事IT行业但又不是学这个专业的,很多人就想通过自学的途径走上这条道路,但大家肯定也和我当初一样有很多的困惑.本人学校学的是国际贸易专业,毕业之后的不顺利加上 ...

  7. 零基础自学编程的程序员如何找到工作

    现在很多年轻人喜欢计算机,喜欢软件开发,想从事IT行业但又不是学这个专业的,很多人就想通过自学的途径走上这条道路,但大家肯定也和我当初一样有很多的困惑.本人学校学的是国际贸易专业,毕业之后的不顺利加上 ...

  8. 长文梳理Muduo库核心代码及优秀编程细节剖析

    一.前言: 代码地址: https://github.com/yyg192/Cpp11-Muduo-MultiReactor  Muduo库是陈硕个人开发的Tcp网络编程库,支持Reactor模型.本 ...

  9. PTA 基础程序编程集 7-2 然后是几点 C语言

    PTA 基础程序编程集 7-2 然后是几点 C语言 有时候人们用四位数字表示一个时间,比如1106表示11点零6分.现在,你的程序要根据起始时间和流逝的时间计算出终止时间. 读入两个数字,第一个数字以 ...

最新文章

  1. 白春礼:探究物质世界奥秘的一把金钥匙——纪念元素周期表发表150周年
  2. 我的总结SVN的使用
  3. 全球与中国聚硫聚合物市场发展前景与投资可行性分析报告2021年版
  4. php文件防删改,PHP实现增删改查以及防SQL注入
  5. Firefox 和 Chrome 性能测试对比
  6. Python 10 行以内代码能有什么高端操作?| 原力计划
  7. SpringBoot2.x集成Apache Shiro并完成简单的Case开发
  8. tensorflow之dropout
  9. 电子相册系统(七)查看原图
  10. c语言小游戏_打字游戏超细讲解(C语言基础小游戏)
  11. Python网络编程笔记二
  12. 2019年区块链多币种钱包建设的安全性与可用性
  13. 世界上第一台计算机论文,世界上公认的第一台电子计算机是1946年诞生。.doc
  14. 推荐几款网盘资源搜索站点,必须收藏 !
  15. 同一用户不同终端登录限制(附:同一浏览器不同用户登录解决方案)
  16. 百度地图爬虫——小试牛刀
  17. 平安人寿“内鬼”泄露近4万条公民信息
  18. Linux之安装node
  19. Fluter基础巩固之Dart语言详解一
  20. 3.Flink-On-Yarn开发使用\原理\Session会话模式\Per-Job模式

热门文章

  1. Hadoop集群的启动顺序
  2. java判断光标位置_Java如何知道光标的当前位置?
  3. LeetCode 144. 二叉树的前序遍历(递归)(迭代)(颜色标记法)
  4. 空格 路径_python处理Windows平台上路径有空格
  5. Tosca :配置环境参数
  6. Javascript深入理解构造函数和原型对象
  7. php array_merge和“+”的区别和使用《细说php2》
  8. UVa340 Master-Mind Hints
  9. window.onload 与 jq的$(function(){})区别
  10. vs2012生成的项目,如何在只装有VS2010的电脑上打开