程序应用动态内存起因:

  • 不晓得本人须要多少对象;
  • 不晓得对象精确类型;
  • 须要多个对象间共享数据

shared_ptr

shared_ptr/weak_ptr 的“计数”在支流平台上是原子操作,没有用锁,性能不俗

auto r = make_shared<int>(42);r=q  //给r赋值,令他指向另一个地址,递增q指向的对象的援用计数,递加r原来指向对象的援用计数,r原来指向的对象主动开释

当一个shared_ptr绑定到一个一般指针时,就将内存治理责任交给了shared_ptr,就不能再用内置指针来拜访shared_ptr指向的内存。shared_ptr能够协调对象的析构,但仅限于其本身的拷贝之间。所以举荐用make_shared而不是new,就能在调配对象的同时与shared_ptr与之绑定,从而防止无心中将同一块内存绑定到了多个独立创立的shared_ptr上

以下调用,将一个长期shared_ptr传递给process。当这个调用表达式完结时,这个长期对象会被销毁,它所指向的内存会被开释

1.int *x(new int(1024);process(x);   //不非法,不能int*转换为shared_ptr<int>     void process(shared_pt<int> ptr){}process(shared_ptr<int>(x));  //非法,但内存会在Process中被开释int j=*x  //未定义,x是个闲暇指针2.shared_ptr<int> p(new int(42));int *q = p.get();{//新程序块shared_ptr<int>(q);}  //程序块完结,q被成果,它指向的内存被开释int foo = *p;  //未定义
reset(p指向的对象援用计数-1)常常与unique一起,管制多个shared_ptr共享的写时复制:if(!p.unique())p.reset(new string(*p));*p += newVal;

unique_ptr (领有他指向的对象惟一管理权,ptr销毁对象也销毁)

不能拷贝或者赋值unique_ptr,能够release/reset将指针所有权从一个unique_ptr转移给另一个

//release将p1置空,是切断对象的管理权,如果不必的话要本人开释资源,auto to_del = p1.release(); delete to_del;unique_ptr<string> p2(p1.release());  unique_ptr<string> p3(new string("xx"));p2.reset(p3.release());  //reset开释了p2原来指向的内存

不能拷贝unique_ptr有个例外:能够拷贝或者赋值一个将要被销毁的Unique_ptr。比方从函数返回一个Unique_ptr

weak_ptr。创立时要用shared_ptr来初始化

auto p = make_shared<int>(42);weak_ptr<int> wp(p);   //wp弱共享p,援用计数未扭转,wp指向的对象可能被开释掉,用wp拜访要用lockdered成员调用check,查看应用vector是否平安以及curr是否在非法范畴内;std::string& StrBlobPtr::deref() const{auto p = check(curr,"dereference past end");return (*P)[curr];}

通过援用计数的形式来实现多个shared_ptr对象间的资源共享。

include <iostream>#include <thread>#include <mutex>///using namespace std;templateclass SharedPtr{public:SharedPtr(T* ptr = nullptr): _ptr(ptr), _pCount(new int(1)), _pMutex(new mutex){// 如果是一个空指针对象,援用计数给0if (ptr == nullptr)*pCount = 0;}SharedPtr(SharedPtr<T>& copy)    : _ptr(copy._ptr)    , _pCount(copy._pCount)    , _pMutex(copy._pMutex){    if (_ptr)        AddCount();}SharedPtr<T>& operator=(const SharedPtr<T>& copy){    // 避免自赋值    if (_ptr != copy_ptr){        // 开释_ptr旧资源        Release();        // 共享copy对象资源        _ptr = copy._ptr;        // 计数减少        _pCount = copy._pCount;        _pMutex = copy._pMutex;        if (_ptr)            AddCount();    }    return *this;}T& operator*() { return *_ptr; }T& operator->() { return _ptr; }// 查看以后计数int UseCount() { return *_pCount; }// 获取原始指针T* Get(){ return _ptr; }// 如果有新对象,减少援用计数int AddCount(){    // 为保障多线程下的线程平安,执行锁操作    _pMutex->lock();    ++(*_pCount);    _pMutex->unlock();    return *_pCount;}// 如果有对象调用析构,缩小援用计数int SubCount(){    _pMutex->lock();    --(*_pCount);    _pMutex->unlock();    return *_pCount;}~SharedPtr(){    Release();}private:    // 开释资源    void Release()    {        // 如果援用计数减为0,则开释资源        if (_ptr && SubCount() == 0){            delete _ptr;            delete _pCount;        }    }private:    int* _pCount;  // 援用计数    T* _ptr;  // 指向治理资源的指针    mutex* _pMutex;  // 互斥锁};int main(){    SharedPtr<int> sp1(new int(10));    cout << "Before Add SP2:" << sp1.UseCount() << endl;    SharedPtr<int> sp2(sp1);    cout << "After Add SP2:" << sp1.UseCount() << endl;        return 0;}