代码1

#include <iostream>
#include <thread>
using namespace std; class A { public:
A() { cout << "A()" << endl; }
~A() { cout << "~A()" << endl; }
void funcA() {
cout << "A function()" << endl;
}
}; void thread_Handler(A *pa) { std::this_thread::sleep_for(std::chrono::seconds(2));
pa->funcA(); } int main() { A *pa = new A(); thread t1(thread_Handler, pa); delete pa; t1.join(); return 0;
} 上面代码的问题:
std::this_thread::sleep_for(std::chrono::seconds(2));
后 pa指针已经main 线程中delete 掉了,删掉之后在访问 funcA()函数是不合理的
应该修改为 void thread_Handler(A *pa) { std::this_thread::sleep_for(std::chrono::seconds(2));
if(pa所指向的对象是否还有效)
{
pa->funcA();
}
} //针对上面的场景,我们可以使用强弱智能指针,修改如下

代码2

#include <iostream>
#include <thread>
using namespace std; class A { public:
A() { cout << "A()" << endl; }
~A() { cout << "~A()" << endl; }
void funcA() {
cout << "A function()" << endl;
}
}; void thread_Handler(weak_ptr<A> pa) { std::this_thread::sleep_for(std::chrono::seconds(2));
shared_ptr<A> ptr = pa.lock();
if (ptr == nullptr) {
cout << "对象已经销毁了" << endl;
}
else {
ptr->funcA();
}
} int main() { {
shared_ptr<A> ptr(new A()); thread t1(thread_Handler, weak_ptr<A>(ptr)); t1.detach();
} std::this_thread::sleep_for(std::chrono::seconds(10));
return 0;
}

share_ptr

share_ptr是C++11新添加的智能指针,它限定的资源可以被多个指针共享。

只有指向动态分配的对象的指针才能交给 shared_ptr 对象托管。将指向普通局部变量、全局变量的指针交给 shared_ptr 托管,编译时不会有问题,但程序运行时会出错,因为不能析构一个并没有指向动态分配的内存空间的指针

weak_ptr

weak_ptr是一种用于解决shared_ptr相互引用时产生死锁问题的智能指针。如果有两个shared_ptr相互引用,那么这两个shared_ptr指针的引用计数永远不会下降为0,资源永远不会释放。weak_ptr是对对象的一种弱引用,它不会增加对象的use_count,weak_ptr和shared_ptr可以相互转化,shared_ptr可以直接赋值给weak_ptr,weak_ptr也可以通过调用lock函数来获得shared_ptr。

weak_ptr指针通常不单独使用,只能和 shared_ptr 类型指针搭配使用。将一个weak_ptr绑定到一个shared_ptr不会改变shared_ptr的引用计数。一旦最后一个指向对象的shared_ptr被销毁,对象就会被释放。即使有weak_ptr指向对象,对象也还是会被释放。

weak_ptr并没有重载operator->和operator *操作符,因此不可直接通过weak_ptr使用对象,典型的用法是调用其lock函数来获得shared_ptr示例,进而访问原始对象。

<二>强弱指针使用场景之 多线程访问共享对象问题的更多相关文章

  1. C++中的智能指针、轻量级指针、强弱指针学习笔记

    一.智能指针学习总结 1.一个非const引用无法指向一个临时变量,但是const引用是可以的! 2.C++中的delete和C中的free()类似,delete NULL不会报"doubl ...

  2. C++实现离散余弦变换(参数为二维指针)

    C++实现离散余弦变换(参数为二维指针) 写在前面 到目前为止已经阅读了相当一部分的网格水印等方面的论文了,但是论文的实现进度还没有更上,这个月准备挑选一些较为经典的论文,将其中的算法实现.在实现论文 ...

  3. C语言里的指针探析——type *name[] 在函数参数里面,是一个二维指针

    type *name[] 在函数参数里面声明和不在函数里面声明其实不一样. type *name[] 如果在函数参数里声明,则name 是一个二维指针,并不是一个指针数组,而如果不在函数参数里声明,则 ...

  4. 通过数组初始化链表的两种方法:指向指针的引用node *&tail和指向指针的指针(二维指针)node **tail

    面试高频题:单链表的逆置操作/链表逆序相关文章 点击打开 void init_node(node *tail,char *init_array) 这样声明函数是不正确的,函数的原意是通过数组初始化链表 ...

  5. 二维指针*(void **)的研究(uC/OS-II案例) 《转载》

    uC/OS-II内存管理函数内最难理解的部分就是二维指针,本文以图文并茂的方式对二维指针进行了详细分析与讲解.看完本文,相信对C里面指针的概念又会有进一步的认识. 一.OSMemCreate( ) 函 ...

  6. 微信公众号开发C#系列-11、生成带参数二维码应用场景

    1.概述 我们在微信公众号开发C#系列-7.消息管理-接收事件推送章节有对扫描带参数二维码事件的处理做了讲解.本篇主要讲解通过微信公众号开发平台提供的接口生成带参数的二维码及应用场景. 微信公众号平台 ...

  7. ZT Android的引用计数(强弱指针)技术及一些问题

    Android的引用计数(强弱指针)技术及一些问题 分类: Android 2013-06-07 18:25 844人阅读 评论(4) 收藏 举报 目录(?)[+] Android C++框架层的引用 ...

  8. 最长公共子序列的C++实现---附二维指针的使用方法

    想了挺久到底第一篇在这儿的博客写什么好,刚好这两天又一次看到动态规划的LCS算法觉得还是有点意思的,就拿来写了写,第一篇博客就发它吧. #include<iostream> #includ ...

  9. 【视频开发】OpenCV中Mat,图像二维指针和CxImage类的转换

    在做图像处理中,常用的函数接口有OpenCV中的Mat图像类,有时候需要直接用二维指针开辟内存直接存储图像数据,有时候需要用到CxImage类存储图像.本文主要是总结下这三类存储方式之间的图像数据的转 ...

  10. Java多线程基础——对象及变量并发访问

    在开发多线程程序时,如果每个多线程处理的事情都不一样,每个线程都互不相关,这样开发的过程就非常轻松.但是很多时候,多线程程序是需要同时访问同一个对象,或者变量的.这样,一个对象同时被多个线程访问,会出 ...

随机推荐

  1. Java中的Optional

    在我们日常的开发中,我们经常会遇到 NullPointerException.如何才能优雅的处理NPE?这里告诉大家一个较为流行的方法 java.util.Optional 使用Optional来修饰 ...

  2. 修改 Docker容器 自动启动/不自动启动,挂载路径,存储位置

    有时候创建容器时忘了添加参数 --restart=always,当 Docker 重启时,容器未能自动启动, 现在要添加该参数怎么办呢,方法有二: 1.Docker 命令修改 docker conta ...

  3. 2. 在 Kubernetes 上安装 Gitlab

    总结: 所需要的三个yaml文件的下载地址:https://files.cnblogs.com/files/sanduzxcvbnm/k8s-gitlab.zip Gitlab官方提供了 Helm 的 ...

  4. GitLab 之 Git LFS 大文件存储的配置

    转载自:https://cloud.tencent.com/developer/article/1010589 1.Git LFS 介绍 Git 大文件存储(Large File Storage,简称 ...

  5. loam详细代码解析与公式推导

    loam详细代码解析与公式推导(基础理论知识) 一.基础坐标变换 loam中欧拉角解算都采用R P Y 的解算方式,即先左乘R, 再左乘P, 最后左乘Y,用矩阵表示为: R = Ry * Rp * R ...

  6. 阿里云服务器部署Web环境

    一.配置阿里云服务器 进入阿里云官方网站(https://www.aliyun.com/). 初次使用的话使用支付宝快速注册账户,并进行个人实名认证. 点击试用中心. 选择第二个,云服务器2核4G. ...

  7. linux安装node和达梦数据库8

    PS.本次测试只是为了项目需要,但是在部署和启动程序的时候发生了一系列的报错,由此记录下来为日后作参考 安装达梦数据库 1. 达梦数据库(DM8)简介 达梦数据库管理系统是武汉达梦公司推出的具有完全自 ...

  8. 利用POI遍历出层级结构的excel表格

    import java.util.ArrayList; import java.util.List; import org.apache.poi.ss.util.CellRangeAddress; p ...

  9. Linux-->vi和vim编辑器的基本操作

    vim编辑器介绍 vi或者vim就是对linux下的文本进行编辑的一种编辑器比如说a.cpp文件这种 Linux会内置vi文本编辑器 Vim可以简单的认为vi的增强版 Linux是区分大小写的! 用法 ...

  10. ubuntu20.04详细安装教程

    1.运行虚拟机,加载一段时间后弹出"安装"界面.语言栏倒数第三个是中文.点击[安装 Ubuntu]. 2.键盘布局,[继续] 3.更新和其他软件,取消[安装Ubuntu时下载更新] ...