代码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. 使用kuboard界面管理k8s集群时使用ConfigMap挂载挂载到pod容器中,映射成一个文件夹

    将 ConfigMap 作为一个数据卷(在挂载时不指定数据卷内子路径,需要指定ConfigMap的子路径)挂载到容器,此时 ConfigMap 将映射成一个文件夹,每一个 KEY 是文件夹下的文件名, ...

  2. Nginx配置中一个不起眼字符"/"的巨大作用

    文章转载自:https://mp.weixin.qq.com/s/QwsbuNIqLpxi_FhQ5pSV3w Nginx作为一个轻量级的,高性能的web服务软件,因其占有内存少,并发能力强的特点,而 ...

  3. Windows 下JDK绿色免安装制作教程

    java自从被oracle收购后,windows下新的版本只有安装版.没有zip免安装. windows安装版有一下坏处 会写注册表 会将java.exe,javaw.exe 等解压到C:\Windo ...

  4. SonarQube 之 gitlab-plugin 配合 gitlab-ci 完成每次 commit 代码检测

    转载自:https://cloud.tencent.com/developer/article/1010601 1.背景介绍 我们知道使用 SonarQube 可以在日常开发中检测代码质量,除了使用 ...

  5. P3250 [HNOI2016] 网络 (树剖+堆/整体二分+树上差分+树状数组)

    解法1: 本题有插入路径和删除路径,在每个节点维护插入堆和删除堆,查询时两者top一样则一直弹出.如果每个节点维护的是经过他的路径,显然有些不好处理,正难则反,每个点维护不经过他的路径,那么x节点出了 ...

  6. git(新)

    Git仓库的工作分区 工作区到暂存区的操作 git init :在当前文件夹创建一个文档库,自动产生一个master分支.当当前文件夹已有文档库时,不会再次创建也不会修改,只会将隐藏的.git文件夹显 ...

  7. IOC常用的创建对象方式

    通过无参构造方法来创建 1.User.java public class User { private String name; public User() { System.out.println( ...

  8. JavaScript事件驱动

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  9. win10本地python第三方库安装成功,但是pycharm项目无法使用解决方案

    一.背景win10本地python第三方库安装成功,但是pycharm项目无法使用解决方案如本地安装的python中的request库,在pycharm项目中居然无法使用,比较郁闷 pip list ...

  10. Linux三剑客sed

    注意sed和awk使用单引号,双引号有特殊解释 sed是Stream Editor(字符流编辑器)的缩写,简称流编辑器. sed是操作.过滤和转换文本内容的强大工具. 常用功能包括结合正则表达式对文件 ...