《白话C++》第10章 STL和boost,Page84 让MySharedPtr持有一个用户自定义的类,尝试输出更加详细的信息。

#include <iostream>
//当指针不可用,用户又要强行用时,一死了之
#include <cassert>
using namespace std;

///用以记录引用计数
struct MyRefCount
{
    int count;

    MyRefCount()
        : count(1)
    {

    }
};

template <typename T>
class MySharedPtr
{
public:
    ///explicit可以防止赋值式构造
    explicit MySharedPtr(T* ptr)
                    ///这里创建引用计数
        : _ptr(ptr), _rc(new MyRefCount)
    {

    }
    ///拷贝构造, 构造一个新的MySharedPtr
    MySharedPtr(MySharedPtr const& sp) ///构造入参是MySharedPtr引用
        : _ptr(sp._ptr), _rc(sp._rc)
    {
        ++ _rc->count;
    }

    MySharedPtr & operator = (MySharedPtr const& sp) ///赋值运算符重载
    {
        if(& sp == this) ///this是个指针
        {
            return *this;
        }
        _ptr = sp._ptr; ///将参数的裸指针和引用计数指针,赋给当前对象
        _rc = sp._rc;

        ++ _rc->count; ///引用计数增加1
        return *this; ///返回当前对象,即一个新的MySharedPtr
    }

    ~MySharedPtr() ///MySharedPtr析构
    {
        --_rc->count;
        ///只有当引用计数为0时,才会删除裸指针,同时删除引用计数指针
        if(_rc->count == 0)
        {
            delete _ptr;
            delete _rc;
        }
    }

    T* operator ->()
    {
        if(_rc->count == 0)
        {
            return nullptr;
        }

        return _ptr;
    }

    T& operator * ()
    {
        assert((_rc->count > 0));
        return * _ptr;
    }

    int GetRefCount() const
    {
        assert((_rc->count > 0));
        return _rc->count;
    }

private:
    T* _ptr;  ///裸指针
    MyRefCount* _rc; ///引用计数
};

struct Student
{
    int _age;
    string _name;
    explicit Student(int age, string name) ///防止赋值式构造
        : _age(age), _name(name)
    {
    }
};

void test()
{
    Student* s1 = new Student(10, "张三");
    cout << s1->_name << endl;
}

void testMySharedPtr()
{
    ///产生了一个全新的智能指针sp1,它分配一个整数的内存
    MySharedPtr <Student> sp1(new Student(10, "张三"));
    cout << "ref count = " << sp1.GetRefCount() << endl; ///
    cout << "sp1->_name = " << sp1->_name << endl;
    {
        ///从sp1拷贝构造出sp2,意味着sp2和sp1各自拥有的裸指针指向同一块内存
        MySharedPtr <Student> sp2(sp1);
        cout << "ref count = " << sp2.GetRefCount() << endl;
        cout << "sp2->_name" << sp2->_name << endl;

        sp2->_age = 15;
        sp2->_name = "李四";
        cout << "sp2->_name" << sp2->_name << endl;
    } ///sp2生命周期结束,被析构

    cout << "sp1->_name " << sp1->_name << endl;
    cout << "ref count = " << sp1.GetRefCount() << endl;
}

int main()
{
//    test();
    testMySharedPtr();

    return 0;
}

  • 7
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值