#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;
}
《白话C++》第10章 STL和boost,Page84 让MySharedPtr持有一个用户自定义的类,尝试输出更加详细的信息。
最新推荐文章于 2024-06-17 21:54:57 发布