智能指针是能够智能化的动态开辟空间和内存释放。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;

}