智能指针

  • Post author:
  • Post category:其他




智能指针是能够智能化的动态开辟空间和内存释放。C++中引入智能指针,是防止我们在动态开辟空间是,由于疏忽大意,导致内存的释放出现问题,最终致使内存泄漏。


智能指针的基本特点:


(1)智能指针管理的是一块内存的释放。


(2)智能指针是一个类,有类似指针的功能。


AutoPtr:

#include<iostream>

using namespace std;

template<typename T>

class AutoPtr

{

public:



AutoPtr(T* ptr=NULL)



:_ptr(ptr)



{}



AutoPtr(AutoPtr<T> & ap)



:_ptr(ap._ptr)



{



ap._ptr = NULL;



}



AutoPtr<T>&operator=(AutoPtr<T>& ap)



{



if (this != &ap)



{



if (_ptr != NULL)



{



delete _ptr;



}



_ptr = ap._ptr;



ap._ptr = NULL;



}



return *this;



}



T& operator* ()



{



return *_ptr;



}



T* operator->()



{



return _ptr;



}



~AutoPtr()



{



if (NULL != _ptr)



{



delete _ptr;



}



}

protected:



T * _ptr;

};

struct Point

{



int x;



int y;

};

void FunTest()

{



int *p = new int[10];



delete [] p;



AutoPtr<int> ap = new int(10);



AutoPtr<int> ap1(ap);



AutoPtr<int> ap2;



ap2 = ap1;



*ap2 = 10;



AutoPtr<Point> ap3(new Point);



(*ap3).x = 10;



ap3->y = 10;

}

int main()

{



FunTest();



return 0;

}


ScopedPtr:


因为智能指针容易出现拷贝时释放两次的情况,所以






ScopedPtr主要是进行

防止拷贝





防止拷贝的两条必须要满足的条件是:



(1)


设置保护限定符(2)对拷贝构造函数和赋值运算符重载进行只声明不定义。










如若只有(2),没有设置保护限定符,若在类外进行定义后,则会出现问题,所以说这两个条件是必不可少的。这样就能够避免上面所出现的问题,但是这样就造成了它在功能上的缺陷。

#include<iostream>

using namespace std;

template<typename T>

class ScopedPtr

{



friend void FunTest();

public:



ScopedPtr(T * ptr = NULL)



:_ptr(ptr)



{}



~ScopedPtr()



{



if (NULL != _ptr)



{



delete _ptr;



_ptr = NULL;



}



}

private:



ScopedPtr (ScopedPtr<T>& ap);



ScopedPtr<T>& operator =(ScopedPtr<T>&ap);

private:



T * _ptr;

};

void FunTest()

{



ScopedPtr<int>ap(new int(10));



//ScopedPtr<int>ap1(ap);

}

int main()

{



FunTest();



return 0;

}


SharedPtr:


SharedPtr指针主要的原理是利用


引用计数的浅拷贝


来实现,通过多开辟4个字节的方式,存储引用计数,当有指针指向这块空间时,引用计数+1。如若析构时,先将这块空间的引用计数降为1,然后在进行析构,避免了析构多次的问题


#include<iostream>

using namespace std;

template<typename T>

class SharedPtr

{

public:



SharedPtr(T* ptr = NULL)



:_ptr(ptr)



, _pCount(new int (1))



{}



SharedPtr(SharedPtr<T>& ap)



:_ptr(ap._ptr)



, _pCount(ap._pCount)



{



(*_pCount)++;



}



SharedPtr<T>& operator=(const SharedPtr<T>& ap)



{



if (this != &ap)



{



if (–(*_pCount) == 0)



{



delete _ptr;



delete _pCount;



}



_ptr = ap._ptr;



_pCount = ap._pCount;



++(*_pCount);



}



return *this;



}



~SharedPtr()



{



if (–(*_pCount) == 0)



{



delete _ptr;



delete _pCount;



}



}

private:



T * _ptr;



int * _pCount;

};

int main()

{



int *p = new int;



int *q = p;



SharedPtr<int> ap1(new int(10));



SharedPtr<int> ap2(ap1);



SharedPtr<int> ap3;



ap3 = ap2;



SharedPtr<int> ap4(new int(20));



return 0;

}

转载于:https://blog.51cto.com/11285984/1767441


关闭菜单