STL的智能指针的引用计数多线程安全???
参考文章:
智能指针对象可以放在堆上吗?需要放在堆上吗?
简单实现
#includeusing namespace std;template class SmartPtr{ public: SmartPtr(T *p); ~SmartPtr(); SmartPtr(const SmartPtr &orig); // 浅拷贝 SmartPtr & operator=(const SmartPtr &rhs); // 浅拷贝private: T *ptr; // 将use_count声明成指针是为了方便对其的递增或递减操作 // 这样针对同一块内存的多个智能指针的use_count都指向同一个内存区域,共同影响这个内存的值 // 保证任一个智能指针的消失都会同步给其他智能指针对象,当最后一个智能指针消失时就可以析构管理的内存了 int *use_count;};template SmartPtr ::SmartPtr(T *p) : ptr(p){ use_count = new int(1);}template SmartPtr ::~SmartPtr(){ // 只在最后一个对象引用ptr时才释放内存 if (--(*use_count) == 0) { delete ptr; delete use_count; ptr = nullptr; use_count = nullptr; cout << "Destructor is called!" << endl; }}template SmartPtr ::SmartPtr(const SmartPtr &orig){ ptr = orig.ptr; use_count = orig.use_count; ++(*use_count); cout << "Copy constructor is called!" << endl;}// 重载等号函数不同于复制构造函数,即等号左边的对象可能已经指向某块内存。// 这样,我们就得先判断左边对象指向的内存已经被引用的次数。如果次数为1,// 表明我们可以释放这块内存;反之则不释放,由其他对象来释放。template SmartPtr & SmartPtr ::operator=(const SmartPtr &rhs){ // 《C++ primer》:“这个赋值操作符在减少左操作数的使用计数之前使rhs的使用计数加1, // 从而防止自身赋值”而导致的提早释放内存 ++(*rhs.use_count); // 将左操作数对象的使用计数减1,若该对象的使用计数减至0,则删除该对象 // 因为左操作数对象可能已经指向某块其他内存 if (--(*use_count) == 0) { delete ptr; delete use_count; cout << "Left side object is deleted!" << endl; } ptr = rhs.ptr; use_count = rhs.use_count; return *this;}复制代码
测试程序
#include#include "smartptr.h"using namespace std;int main(){ // Test Constructor and Assignment Operator Overloaded SmartPtr p1(new int(0)); p1 = p1; // Test Copy Constructor SmartPtr p2(p1); // Test Assignment Operator Overloaded SmartPtr p3(new int(1)); p3 = p1; return 0;}复制代码