C++智能指针(二)模拟实现三种智能指针
来源:互联网 发布:法医秦明 知乎 编辑:程序博客网 时间:2024/05/18 01:21
在上一篇博客中提到了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;}
//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;}
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;}
0 0
- C++智能指针(二):模拟实现三种智能指针
- C++智能指针(二)模拟实现三种智能指针
- 智能指针模拟C
- 模拟实现智能指针
- 模拟实现智能指针
- 模拟实现智能指针
- 模拟实现智能指针
- 模拟实现智能指针SharePtr
- 智能指针的模拟实现
- 智能指针(二)
- 智能指针(二)
- 一步一步 实现智能指针(三)
- 一步一步 实现智能指针(二)
- 【C++】智能指针的实现
- [c++]智能指针的实现
- C 语言实现智能指针
- (C++)智能指针的模拟实现及使用
- 智能指针模拟A
- JAVA中==和equals方法的区别,简单易懂
- 我的个人博客地址
- nyoj-最小步数
- 二叉搜索树详解及实现代码(BST)
- Easy 3 Palindrome Number(9)
- C++智能指针(二)模拟实现三种智能指针
- 03-Java 逻辑运算符和条件语句
- Java 接口的使用
- online free data source
- 01-复杂度1 最大子列和问题 (20分)
- zoj 3954 Seven-Segment Display 思维
- [sdoi2017][bzoj4819] D2T1 新生舞会
- thinkphp开发总结(二)——同时连接mysql与mongodb数据库
- 一分钟搞定触手app主页酷炫滑动切换效果