https://blog.csdn.net/nou_camp/article/details/70186721
在上一篇博客中提到了Auto_ptr(C++智能指針(一)),下面進行模擬實現Auto_ptr?
采用類模板實現
#include<iostream>
using namespace std;
template<class T>
class Autoptr
{
public:Autoptr(T* ptr = NULL):_ptr(ptr){}//Autoptr():_ptr(NULL)//{}Autoptr(Autoptr<T>& ap){this->_ptr = ap._ptr;ap._ptr = NULL;}Autoptr<T>& operator=(Autoptr<T>& sp){if (this != &sp){delete this->_ptr;_ptr = sp._ptr;sp._ptr = NULL;}return *this;}T* operator->(){return _ptr;}T operator*(){return *_ptr;}~Autoptr(){delete _ptr;_ptr = NULL;}void Reset(T* ptr = 0){if (_ptr != ptr){delete _ptr;}_ptr = ptr;}
protected:T* _ptr;
};void test()
{//int *p1 = new int(10);//Autoptr<int>ap1(p1);Autoptr<int> ap1(new int(10));//上面的兩行代碼可以直接用本行代碼代替cout << *ap1 << endl;Autoptr<int> ap2(ap1);cout << *ap2 << endl;Autoptr<int> ap3(new int(20));ap3 = ap2;cout << *ap3 << endl;//cout << *ap1 << endl;//會使代碼出錯
}
int main()
{test();system("pause");return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
?
//cout << *ap1 << endl;//會使代碼出錯?
這是test函數中的代碼,執行這句代碼,會使程序崩潰,這是因為ap1已經把它指向的空間交給了ap2去管理,所以ap1已經不具備訪問原來自己所指向的空間的權限。所以對它進行解引用是非法的。?
所以可以看清auto_ptr的本質是管理權的轉移,即ap1將自己所指向的空間交給ap2來管理,析構也是由ap2來完成。
由上面可知auto_ptr有嚴重缺陷,所以后來有人寫了scopedptr,慢慢發展形成了第三方庫。?
scopedptr ->防拷貝,意思就是不能進行拷貝,簡單地說是一種簡單粗暴的方式。下面模擬實現scopedptr。采用模板類實現。
template<class T>
class scopedptr
{
public:scopedptr(T *ptr):_ptr(ptr){}T* operator->(){return _ptr;}T operator*(){return *_ptr;}~scopedptr(){delete _ptr;_ptr = NULL;}
protected:scopedptr<T>& operator=(const scopedptr<T>& s);scopedptr(scopedptr<T>& ap);
private:T* _ptr;
};
void test()
{scopedptr<int> s1(new int(10));//scopedptr<int> s2(s1);//有錯誤,編譯不通過cout << *s1 << endl;
}
int main()
{test();system("pause");return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
scopedptr中對拷貝構造函數和賦值運算符的重載函數只是進行了聲明,并沒有去定義這兩個函數,而且聲明為protected或者是private,這是防止別人在類外對這兩個函數進行定義。防止拷貝,所以說scopedptr是一種簡單粗暴的方式。
編寫程序往往要用到拷貝,這樣scopedptr就不能起到相應的作用,所以便有了shared_ptr。?
shared_ptr->采用了引用計數,優點是功能強大,但是也有缺點,缺點是過于復雜,而且會引起循環引用。?
下面模擬實現shared_ptr
#include<iostream>
using namespace std;
template<class T>
class sharedptr
{
public:sharedptr(T* ptr) //構造:_ptr(ptr), _refcount(new int(1)){}sharedptr() //構造:_ptr(NULL), _refcount(new int(1)){}sharedptr(const sharedptr<T>& sp) //拷貝構造:_ptr(sp._ptr), _refcount(sp._refcount){(*_refcount)++;}sharedptr<T>& operator=(const sharedptr<T>& sp) //賦值運算符的重載{if (_ptr != sp._ptr){delete _ptr;delete _refcount;_ptr = sp._ptr;_refcount = sp._refcount;++(*_refcount);}return *this;}~sharedptr() //析構{Realease();}T& operator*(){return *_ptr;}T* operator->(){return _ptr;}T Getrefcount(){return *(_refcount);}inline void Realease(){if (--*_refcount == 0){delete _refcount;delete _ptr;}}void Reset(T* ptr ,T* refcount){if (_ptr != ptr){delete _ptr;delete _refcount;}_ptr = ptr;_refcount = refcount;}
public:T* _ptr;T* _refcount;//T _refcount;//有缺陷//int static _refcount;//有缺陷
};
void test()
{sharedptr<int> s1(new int(10));//cout << *s1._refcount << endl;cout << s1.Getrefcount() << endl;sharedptr<int> s2(s1);//cout << *s2._refcount << endl;cout << s2.Getrefcount() << endl;sharedptr<int> s3(new int(20));s3 = s1;//cout << *s3._refcount << endl;cout << s3.Getrefcount() << endl;
}
int main()
{test();//*sharedptr<int> sp; // 驗證Reset//sp.Reset(new int,new int(1)); //*sp = 10;//cout << *sp << endl;//sp.Reset(new int, new int(1)); //*sp = 20;//cout << *sp << endl;//sp.Reset(); system("pause");return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96