栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

shared

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

shared

shared_ptr代码实现,当前命名为ushared_ptr。
1、定义模板指针T* ptr_和计数指针int* red_count_.
2、空构造。
3、实例化构造,获取真实类型对象,并且计数new为1.
4、创建引用函数,通过参数获取真实类型对象和计数指针对象,并且计数加一。
5、重载operator=函数,通过参数获取真实类型对象和计数指针对象,并且计数加一。
6、重载 operator*和operator-> 实现指针功能。
7、创建获取真实类型对象的函数。
8、创建获取计数的函数。
9、创建析构函数,计数减一,当计数为0时析构真实类型对象。
代码及测试如下:

#include 
#include 
#include 
#include 
#include 
#include 

template 
class ushared_ptr {
private:
    // 保存真实指针
    T* ptr_;
    // 指向引用计数
    int* ref_count_;

public:
    // 空构造。
    ushared_ptr():ref_count_(NULL),ptr_(NULL) {}
    // 构造函数
    ushared_ptr(T *t) {
        ptr_ = t;
        // 初始化引用计数
        ref_count_ = new int(1);
        qWarning()<<"ushared_ptr num"<<*ref_count_;
    }
    // 引用
    ushared_ptr(ushared_ptr& ptr) {
        ptr_ = ptr.ptr_;
        // 引用计数加1
        ref_count_ = ptr.ref_count_;
        (*ref_count_)++;
        qWarning()<<"ushared_ptr num"<<*ref_count_;
    }
    // 重载operator=,然后将新的对象引用次数加一。
    void operator =(ushared_ptr& ptr) {
        ptr_ = ptr.ptr_;
        // 引用计数加1
        ref_count_ = ptr.ref_count_;
        (*ref_count_)++;
        qWarning()<<"ushared_ptr num"<<*ref_count_;
    }
    // 析构
    ~ushared_ptr()
    {
        if (ptr_)
        {
            qWarning()<<"~ushared_ptr num"<<*ref_count_;
            if (--(*ref_count_) == 0)
            {
                qWarning()<<"~ushared_ptr delete"<<*ref_count_;
                delete ref_count_;
                delete ptr_;
            }
            else
                qWarning()<<"~ushared_ptr delete"<<*ref_count_;   
        }
    }
    // 重载 operator*和operator-> 实现指针功能
    T operator *() {return *ptr_;}
    T* operator ->() {return ptr_;}
    // 获取原指针
    T* get() {return ptr_;}
    // 获取计数
    int use_count(){if(ref_count_)return *ref_count_;}
};

class B;
class A
{
public:
    ushared_ptr m_b;
    A(){}
    ~A(){qWarning()<<"~A->B num"< m_a;
    B(){}
    ~B(){qWarning()<<"~B->A num"< a(new A);
    ushared_ptr b(new B);
    qWarning()<<"A num"<m_b = b;
    //b->m_a = a;
    qWarning()<<"A num"< 

weak_ptr辅助性智能指针,它的作用就是辅助shared_ptr来使用的,帮助shared_ptr解除多个对象都引用对方指针,造成引用成环的问题,它的原理在于它是一种弱引用,它的各种操作不改变shared_ptr的计数大小的。
如以下例子:

class B;
class A
{
public:
    std::shared_ptr m_b;
    A(){}
    ~A(){qWarning()<<"~A->B num"< m_a;
    B(){}
    ~B(){qWarning()<<"~B->A num"< a(new A);
    std::shared_ptr b(new B);
    qWarning()<<"A num"<m_b = b;
    b->m_a = a;
    qWarning()<<"A num"< 

结果

A num 1
B num 1
A num 2
B num 2

初始化和赋值后:A的计数为2,B的计数2。a,b跑出作用域后,AB的智能指针进入析构,A的计数减1为1,B的计数减1为1。两边都为1,因此–(*ref_count_) == 0的条件不成立,都无法进入条件语句内部将A和B的对象delete,所以A和B的析构函数都不会进,也就无法继续后面的操作,会出内存泄露。

当使用了weak_ptr后
如以下:

class B;
class A
{
public:
    std::shared_ptr m_b;
    A(){}
    ~A(){qWarning()<<"~A->B num"< m_a;
    B(){}
    ~B(){qWarning()<<"~B->A num"< a(new A);
    std::shared_ptr b(new B);
    qWarning()<<"A num"<m_b = b;
    b->m_a = a;
    qWarning()<<"A num"< 

结果:

A num 1
B num 1
A num 1
B num 2
~A->B num 1
~B->A num 0

通过结构可以看出,b->m_a = a后A计数仍为1,weak_ptr对shared_ptr的计数不做修改。
初始化和赋值后:A的计数为1,B的计数为2。当a跑出作用域后,A的智能指针进入析构,A的计数减1为0,满足–(*ref_count_) == 0的条件,A会被delete,因此进入A的析构函数,智能指针m_b为A的成员变量,所以它会被析构,然后B的智能指针进入析构函数,B计数减1为1。当b跑出作用域后,B的智能指针进入析构,B的计数减1为0,满足–(*ref_count_) == 0的条件,B会被delete,因此进入B的析构函数,m_a为B的成员变量,它会被析构,此时此刻所有指针都被析构,没有内存泄露。

转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号