文档章节

C++11中的智能指针

临峰不畏
 临峰不畏
发布于 2015/06/12 13:27
字数 696
阅读 5228
收藏 14
点赞 0
评论 1


在C++11中,引入了智能指针。主要有:unique_ptr, shared_ptr, weak_ptr。
这3种指针组件就是采用了boost里的智能指针方案。很多有用过boost智能指针的朋友,很容易地就能发现它们之间的关间:

std boost 功能说明
unique_ptr scoped_ptr 独占指针对象,并保证指针所指对象生命周期与其一致
shared_ptr shared_ptr 可共享指针对象,可以赋值给shared_ptr或weak_ptr。
指针所指对象在所有的相关联的shared_ptr生命周期结束时结束,是强引用。
weak_ptr weak_ptr 它不能决定所指对象的生命周期,引用所指对象时,需要lock()成shared_ptr才能使用。

C++11将boost里的这一套纳入了标准。

如下为示例代码:

//文件 test-1.cpp
#include <memory>
#include <iostream>

using namespace std;

int main()
{
    unique_ptr<int> up1(new int(11));
    unique_ptr<int> up2 = up1;   //! 编译时会出错 [1]

    cout << *up1 << endl;
    unique_ptr<int> up3 = move(up1);  //! [2]
    cout << *up3 << endl;
    if (up1)
        cout << *up1 << endl;

    up3.reset();  //! [3]
    up1.reset();

    shared_ptr<string> sp1(make_shared<string>("Hello"));
    shared_ptr<string> sp2 = sp1;
    cout << "*sp1:" << *sp1 << endl;
    cout << "*sp2:" << *sp2 << endl;
    sp1.reset();
    cout << "*sp2:" << *sp2 << endl;

    weak_ptr<string> wp = sp2; //! [4]
    cout << "*wp.lock():" << *wp.lock() << endl;
    sp2.reset();
    cout << "*wp.lock():" << *wp.lock() << endl;  //! 运行时会出错
    return 0;
}
//编译命令: g++ -std=c++11 test-1.cpp

[1]: unique_ptr 是禁止复制赋值的,始终保持一个 unique_ptr 管理一个对象。
[2]: unique_ptr 虽然不能赋值,但可以通过 move() 函数转移对象的所有权。一旦被 move() 了,原来的 up1 则不再有效了。
[3]: reset() 可以让 unique_ptr 提前释放指针。
[4]: 由 shared_ptr 构造一个 weak_ptr

shared_ptr 与 weak_ptr

如下面的示例:

shared_ptr<string> s1(new string);
shared_ptr<string> s2 = s1;
weak_ptr<string> w1 = s2;

在内存中:

s1, s2, w1 都指向一个 ptr_manage 的对象。
在该对象中有 shared_ref_countweak_ref_count 两个域分别记录引用它的 shared_ptrweak_ptr 的个数。这个很容易办到,只要在复制构造与赋值函数中对相当地引用值进行加1,在析构中减1即可。ptr_manage 中的 ptr 域存放真正的对象指针地址。

shared_ref_cnt 被减为0时,自动释放 ptr 指针所指向的对象。当 shared_ref_cntweak_ref_cnt 都变成0时,才释放 ptr_manage 对象。
如此以来,只要有相关联的 shared_ptr 存在,对象就存在。weak_ptr 不影响对象的生命周期。当用 weak_ptr 访问对象时,对象有可能已被释放了,要先 lock()

当执行:

s1.reset()

此时:

shared_ref_cnt 由2减成了1。

再执行:

s2.reset()

此时:

shared_ref_cnt 已被减到0了,ptr 所对应的object已被释放,ptr 被清0。此时,ptr_manage 依旧保留。因为 w1 还需要引用它。

在最后,w1 也析构了的时候:

ptr_manage 中的 weak_ref_cnt 被减成0,最后连 ptr_manage 都释放了。

© 著作权归作者所有

共有 人打赏支持
临峰不畏
粉丝 211
博文 183
码字总数 96576
作品 0
深圳
技术主管
加载中

评论(1)

sx_wxy
sx_wxy
79
C++ 11和C++98相比有哪些新特性

此文是如下博文的翻译: https://herbsutter.com/elements-of-modern-c-style/ C++11标准提供了许多有用的新特性。这篇文章特别针对使C++11和C++98相比看上去像一门新语言的特性,因为: C+...

harlanc
2017/03/05
0
0
C++11 智能指针

原作者:BabuAbdulsalam 本文翻译自CodeProject,转载请注明出处。 引入 尽管有另外一篇文章说里的智能指针了。近来,我听到许多人谈论新标准,就是所谓的。 我研究了一下的一些语言特性,发...

2017/12/28
0
0
消灭“脑细胞杀手”,阿里专家带你深入C++对象的生命周期管理

摘要:C/C++的指针一直是令人又爱又恨的特性。围绕指针产生了许许多多优雅的数据结构和系统实现,但又滋生了不少“脑细胞杀手”——内存Bug。C/C++指针问题(空指针、野指针、垂悬指针)的根...

萌萌怪兽
04/18
0
0
c++ primer 第五版学习笔记

第二章 函数体外定义的内置类型变量会初始化为0,函数体外的是未初始化的 用constexpr声明变量表示它是一个常量表达式(编译器可以确定的值),且只能应用于字面值 c++11中可以用 来定义一个...

David栗子
2017/12/11
0
0
C++智能指针的分析与使用

手动管理的弊端 在简单的程序中,我们不大可能忘记释放 new 出来的指针,但是随着程序规模的增大,我们忘了 delete 的概率也随之增大。在 C++ 中 new 出来的指针,赋值意味着引用的传递,当赋...

Tanswer_
01/11
0
0
C++-智能指针——简单实现分析

一:为什么要有智能指针 在我们动态开辟内存时,每次new完就一定会有配套的delete来完成释放操作。可是这时候问题就来了,有时候程序未必会执行到我们释放的那一步,说不定在中间部分就进行了...

sssssuuuuu666
2017/08/03
0
0
Visual Studio 2015 Update 1 RC 发布

Visual Studio 2015 Update 1 RC 发布,此版本给 C++ 开发者提供了很多新特性: 编译器改进:更新了 C++ 编译器和标准库,支持 C++11 和 C++14 跨平台 C++ 移动开发支持:Android 开发者可以...

oschina
2015/10/30
4.6K
40
个人以前经常犯的5大C++作死行为。

真心地,每看一遍自己以前的代码就想骂自己一遍,作死啊,真的是too young too simple, sometimes naive啊。给大家分享一下,求喷。 1.new出一个指针后判断它是否为空。 class Test{public:...

梦游的睡鼠
2014/05/18
1K
5
一个函数指针模板,向std::function致敬

两年前写这个是因为学C++11练手。而且也因为sizeof(std::function<void()>)的大小有点大,不是指针大小。所以自己写个只有指针大小的版本,不过功能就少很多。 这样就可以这么用: 基本的思路...

大止刀口
2016/05/02
255
0
关于std::shared_ptr与std::enable_shared_from_this循环引用导致的问题

自从C++11有了std::sharedptr这样的智能指针,作为C++程序只要将一个堆上的类对象用std::sharedptr包裹一下就可以做到内存自动释放了。看一个例子: #include "stdafx.h" include class A{pu...

analogous_love
2017/12/21
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

expect脚本同步文件、expect脚本指定host和要同步的文件、构建文件分发系统

expect脚本同步文件 更改权限 执行脚本 查看执行结果 expect eof需要加上,作用是等脚本命令执行完再进行退出 expect脚本指定host和要同步的文件 更改权限,执行脚本 构建文件分发系统 需求背...

Zhouliang6
14分钟前
1
0
Hive应用:外部分区表

Hive应用:外部分区表 介绍 Hive可以创建外部分区表。创建表的时候,分区要在建表语句中体现。建完之后,你不会在表中看到数据,需要进行分区添加,使用alter语句进行添加。然后数据才会显示...

星汉
24分钟前
0
0
点击Enter登录

1. 效果 2. 实现过程(记得引入jq文件) //6.回车事件 登录 $(function() { document.onkeydown = function(event) { var e = event || window.event || arguments.callee.caller.arguments......

Lucky_Me
29分钟前
1
0
点击菜单内容切换

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> .menu{ height: 38px; background-color: #eeeeee; line-height: 38px; } .mao{ ......

南桥北木
今天
1
0
OSChina 周六乱弹 —— 妹子和游戏哪个更好玩

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @andonny :分享唐朝乐队的单曲《国际歌》 《国际歌》- 唐朝乐队 手机党少年们想听歌,请使劲儿戳(这里) @举个栗子- :日常祈雨 邪恶的大祭...

小小编辑
今天
481
6
流利阅读笔记32-20180721待学习

“人工智能”造假:只有人工,没有智能 Lala 2018-07-21 1.今日导读 当今社会,擅长单个方面的人工智能已经盛行,手机借助 AI 智慧防抖技术帮助大家拍出清晰照片,谷歌研发的 AI 助手将可以帮...

aibinxiao
今天
6
0
我的成长记录(一)

今天突然精神抖擞,在我的博客下新开一项分类>成长记录,专门记录每隔一段时间我的一点感悟吧。因为今天才专门花时间新开这样一个分类,所以以前有过的一些感悟没有记录下来,现在已经想不起...

dtqq
今天
1
0
机器学习管理平台 MLFlow

最近工作很忙,博客一直都没有更新。抽时间给大家介绍一下Databrick开源的机器学习管理平台-MLFlow。 谈起Databrick,相信即使是不熟悉机器学习和大数据的工程湿们也都有所了解,它由Spark的...

naughty
今天
11
0
idea tomcat 远程调试

tomcat 配置 编辑文件${tomcat_home}/bin/catalina.sh,在文件开头添加如下代码。    CATALINA_OPTS="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=7829" Idea端配......

qwfys
今天
2
0
遍历目录下的文件每250M打包一个文件

#!/usr/bin/env python # -*- utf-8 -*- # @Time : 2018/7/20 0020 下午 10:16 # @Author : 陈元 # @Email : abcmeabc@163.com # @file : tarFile.py import os import tarfile import thr......

寻爱的小草
今天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部