Boost智能指针——weak_ptr .

news/2024/7/6 1:13:45 标签: class, c
cle class="tags" href="/tags/CLASS.html" title=class>class="baidu_pl">
cle_content" class="tags" href="/tags/CLASS.html" title=class>class="article_content clearfix">
content_views" class="tags" href="/tags/CLASS.html" title=class>class="htmledit_views">

 http://blog.csdn.net/afrish/article/details/3985636

 

 

color:red">【通知】关于近期用户博文被恶意投票的解决办法         color:red">bShare分享࿰c;迅速提升10倍流量

cle_details" class="tags" href="/tags/CLASS.html" title=class>class="details">
class="tags" href="/tags/CLASS.html" title=class>class="article_title"> class="tags" href="/tags/CLASS.html" title=class>class="ico ico_type_Repost">

class="tags" href="/tags/CLASS.html" title=class>class="link_title">Boost智能指针——weak_ptr

class="tags" href="/tags/CLASS.html" title=class>class="article_manage"> class="tags" href="/tags/CLASS.html" title=class>class="link_categories">分类: BOOST class="tags" href="/tags/CLASS.html" title=class>class="link_postdate">2009-03-12 22:58 class="tags" href="/tags/CLASS.html" title=class>class="link_view" title="阅读次数"> 815人阅读 class="tags" href="/tags/CLASS.html" title=class>class="link_comments" title="评论次数">评论(1) class="tags" href="/tags/CLASS.html" title=class>class="link_collect">收藏 class="tags" href="/tags/CLASS.html" title=class>class="link_report"> 举报
class="tags" href="/tags/CLASS.html" title=class>class="article_content">
class="tags" href="/tags/CLASS.html" title=class>class="postTitle"> Boost智能指针——weak_ptr

循环引用:

引用计数是一种便利的内存管理机制࿰c;但它有一个很大的缺点࿰c;那就是不能管理循环引用的对象。一个简单的例子如下:

color:blue">#include color:#a31515"><string>
color:blue">#include color:#a31515"><iostream>
color:blue">#include color:#a31515"><boost/shared_ptr.hpp>
color:blue">#include color:#a31515"><boost/weak_ptr.hpp>

color:blue">class="tags" href="/tags/CLASS.html" title=class>class parent;
color:blue">class="tags" href="/tags/CLASS.html" title=class>class children;

color:blue">typedef boost::shared_ptr<parent> parent_ptr;
color:blue">typedef boost::shared_ptr<children> children_ptr;

color:blue">class="tags" href="/tags/CLASS.html" title=class>class parent
{
color:blue">public:
    ~parent() { std::cout <<color:#a31515">"destroying parent/n"; }

color:blue">public:
    children_ptr children;
};

color:blue">class="tags" href="/tags/CLASS.html" title=class>class children
{
color:blue">public:
    ~children() { std::cout <<color:#a31515">"destroying children/n"; }

color:blue">public:
    parent_ptr parent;
};


color:blue">void test()
{
    parent_ptr father(color:blue">new parent());
    children_ptr son(color:blue">new children);

    father->children = son;
    son->parent = father;
}

color:blue">void main()
{
    std::cout<<color:#a31515">"begin test.../n";
    test();
    std::cout<<color:#a31515">"end test./n";
}

运行该程序可以看到࿰c;即使退出了test函数后࿰c;由于parent和children对象互相引用࿰c;它们的引用计数都是1࿰c;不能自动释放࿰c;并且此时这两个对象再无法访问到。这就引起了c++中那臭名昭著的color:#c0504d">内存泄漏

一般来讲࿰c;解除这种循环引用有下面有三种可行的方法:

  1. 当只剩下最后一个引用的时候需要手动打破循环引用释放对象。
  2. 当parent的生存期超过children的生存期的时候࿰c;children改为使用一个普通指针指向parent。
  3. 使用弱引用的智能指针打破这种循环引用。

虽然这三种方法都可行࿰c;但方法1和方法2都需要程序员手动控制࿰c;麻烦且容易出错。这里主要介绍一下第三种方法和boost中的弱引用的智能指针boost::weak_ptr。

强引用和弱引用

一个强引用当被引用的对象活着的话࿰c;这个引用也存在(就是说࿰c;当至少有一个强引用࿰c;那么这个对象就不能被释放)。boost::share_ptr就是强引用。

相对而言࿰c;弱引用当引用的对象活着的时候不一定存在。仅仅是当它存在的时候的一个引用。弱引用并不修改该对象的引用计数࿰c;这意味这弱引用它并不对对象的内存进行管理࿰c;在功能上类似于普通指针࿰c;然而一个比较大的区别是࿰c;弱引用能检测到所管理的对象是否已经被释放࿰c;从而避免访问非法内存。

boost::weak_ptr

boost::weak_ptr<T>是boost提供的一个弱引用的智能指针࿰c;它的声明可以简化如下:

color:blue">namespace boost {

    color:blue">template<color:blue">typename T> color:blue">class="tags" href="/tags/CLASS.html" title=class>class weak_ptr {
    color:blue">public:
        color:blue">template <color:blue">typename Y>
        weak_ptr(color:blue">const shared_ptr<Y>& r);

        weak_ptr(color:blue">const weak_ptr& r);

        ~weak_ptr();

        T* get() color:blue">const;
        color:blue">bool expired() color:blue">const;
        shared_ptr<T> lock() color:blue">const;
    };
}

可以看到࿰c;boost::weak_ptr必须从一个boost::share_ptr或另一个boost::weak_ptr转换而来࿰c;这也说明࿰c;进行该对象的内存管理的是那个强引用的boost::share_ptr。boost::weak_ptr只是提供了对管理对象的一个访问手段。

boost::weak_ptr除了对所管理对象的基本访问功能(通过get()函数)外࿰c;还有两个常用的功能函数:expired()用于检测所管理的对象是否已经释放;lock()用于获取所管理的对象的强引用指针。

通过boost::weak_ptr来打破循环引用

由于弱引用不更改引用计数࿰c;类似普通指针࿰c;只要把循环引用的一方使用弱引用࿰c;即可解除循环引用。对于上面的那个例子来说࿰c;只要把children的定义改为如下方式࿰c;即可解除循环引用:

color:blue">class="tags" href="/tags/CLASS.html" title=class>class children
{
color:blue">public:
    ~children() { std::cout <<color:#a31515">"destroying children/n"; }

color:blue">public:
    boost::weak_ptr<parent> parent;
};

最后值得一提的是,虽然通过弱引用指针可以有效的解除循环引用࿰c;但这种方式必须在程序员能预见会出现循环引用的情况下才能使用࿰c;也可以是说这个仅仅是一种编译期的解决方案࿰c;如果程序在运行过程中出现了循环引用࿰c;还是会造成内存泄漏的。因此࿰c;不要认为只要使用了智能指针便能杜绝内存泄漏。毕竟࿰c;对于C++来说࿰c;由于没有垃圾回收机制࿰c;内存泄漏对每一个程序员来说都是一个非常头痛的问题。

 

cle>

http://www.niftyadmin.cn/n/790301.html

相关文章

MongoDB中的 Limit和Skip方法实现分页,Sort实现排序,Count实现统计个数,distinct去除重复数据(八)

MongoDB也有Limit读取指定数量的数据记录&#xff0c;Skip 跳过指定数量的数据&#xff0c;它俩结合起来就可以做一个分页 Sort是MongoDB内置的排序方法&#xff0c;和上面的Limit&#xff0c;Skip可以合用 准备测试数据 > db.col.find() { "_id" : ObjectId(&qu…

利用office2000组件进行填充打印报不支持集合。 (Exception from HRESULT: 0x80020011 (DISP_E_NOTACOLLECTION))...

环境&#xff1a;win2008 64位.net4.0 office2000 错误提示&#xff1a; 不支持集合。 (Exception from HRESULT: 0x80020011 (DISP_E_NOTACOLLECTION)) at System.RuntimeType.ForwardCallToInvokeMember(String memberName, BindingFlags flags, Object target, Int32[] aWra…

《我的泛型编程观》之boost.scoped_ptr、scoped_array源码分析

http://hi.baidu.com/_%E2d_%B7%B3_%DE%B2%C2%D2/blog/item/1d7739d92055bb2610df9b5c.html 《我的泛型编程观》之boost.scoped_ptr、scoped_array源码分析 2009年12月06日 星期日 下午 06:57boost.scoped_ptr已经被tr2建议作为C标准库的一部分&#xff0c;它的兄弟shared_ptr已…

Qt内建对话框简介

http://www.iteye.com/topic/711655 1.QErrorMessage 错误信息对话框 QErrorMessage提供了一个错误信息显示的对话框。 一个错误信息部件由一个文本域和一个复选框组成。复选框让用户控制是否下一次还显示这个错误信息&#xff0c;通常显示的文本为“Show this message again…

MongoDB聚合(管道) 九

MongoDB中聚合(aggregate)主要用于处理数据(诸如统计平均值,求和等)&#xff0c;并返回计算后的数据结果。有点类似sql语句中的 count(*)。 语法&#xff1a; db.collection.aggregate(AGGREGATE_OPERATION) //AGGREGATE_OPERATION是下面的表中的聚合表达式和管道结合的产物下…

Qt 设置窗口居中显示

Qt 设置窗口居中显示 (2010-11-30 10:23:31) 方法一&#xff1a;在窗口(QWidget类及派生类)的构造函数中添加如下代码&#xff1a; #include <QDesktopWidget> //....... QDesktopWidget* desktop QApplication::desktop(); // qApp->desktop();也可以 move((deskt…

MongoDB之索引(十)

如果学过关系型数据库比如MySQL那你就应该明白索引的好处&#xff0c;尤其是对于数据量非常大的数据集特别明显 下面的所有的first 代表的是集合 准备数据 >for(i0;i<10000;i){db.first.insert({title:"标题"i})} //可以直接用命令行for循环添加数据我就不全…

QT模态对话框及非模态对话框学习

http://blog.sina.com.cn/s/blog_6143523a0100rxvl.html QT模态对话框及非模态对话框 模态对话框&#xff08;Modal Dialog&#xff09;与非模态对话框&#xff08;Modeless Dialog&#xff09;的概念不是Qt所独有的&#xff0c;在各种不同的平台下都存在。又有叫法是称为模式对…