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