C++智能指针(二):模拟实现三种智能指针
2017-08-10 21:47
531 查看
上一篇博客我们简单介绍了智能指针:简单介绍智能指针
有关shared_ptr的循环引用问题可以参考博客:weak_ptr–解决shared_ptr循环引用问题
测试结果:
答:为了重置一个auto_ptr对象,必须使用reset()函数。可以向reset()传递一个指针,如果不希望设置该auto_ptr对象的话,可以传递一个0值。如果auto_ptr当前指向一个对象并且该auto_ptr对象拥有该对象的所有权,则该对象再底层指针重置之前,首先被删除。例如:
输出结果:
我们可以在输出结果的第二行看到,pi已经变成了随机值。reset()函数将auto_ptr对象原来指向的那块动态分配的空间释放了。
上面的代码还有一句:
为什么报错??
这是因为ap1已经把它指向的空间交给了ap2去管理,所以ap1已经不具备访问原来自己所指向的空间的权限。所以对它进行解引用是非法的。
所以可以看清auto_ptr的本质是管理权的转移,即ap1将自己所指向的空间交给ap2来管理,析构也是由ap2来完成。
scoped_ptr中对拷贝构造函数和赋值运算符的重载函数只是进行了声明,并没有去定义这两个函数,而且声明为protected或者是private,这是防止别人在类外对这两个函数进行定义。防止拷贝,所以说scope_dptr是一种简单粗暴的方式。
shared_ptr->采用了引用计数,优点是功能强大,但是也有缺点,缺点是过于复杂,而且会引起循环引用。
测试结果:
有关shared_ptr的循环引用问题可以参考博客:weak_ptr–解决shared_ptr循环引用问题
auto_ptr
模拟实现
template<class 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) { delete _ptr; _ptr = ap._ptr; ap._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 APTest() { Autoptr<int> ap1(new int(10)); cout <<"*ap1 = "<< *ap1 << endl; Autoptr<int> ap2(ap1); cout <<"*ap2 = "<< *ap2 << endl; Autoptr<int> ap3(new int(20)); ap3 = ap2; cout <<"*ap3 = "<< *ap3 << endl; //cout << *ap1 << endl;//报错 }
测试结果:
代码分析
代码中的Reset()函数是干嘛的?void Reset(T* ptr = 0) { if (_ptr != ptr) { delete _ptr; } _ptr = ptr; }
答:为了重置一个auto_ptr对象,必须使用reset()函数。可以向reset()传递一个指针,如果不希望设置该auto_ptr对象的话,可以传递一个0值。如果auto_ptr当前指向一个对象并且该auto_ptr对象拥有该对象的所有权,则该对象再底层指针重置之前,首先被删除。例如:
void APTest() { int *pi = new int(20); auto_ptr<int>_auto_ptr(pi); cout << "_auto_ptr = " << *pi << endl; int *pi2 = new int(30); _auto_ptr.reset(pi2); cout << "pi->" << *pi << endl; cout << "pi2->" << *pi2 << endl; }
输出结果:
我们可以在输出结果的第二行看到,pi已经变成了随机值。reset()函数将auto_ptr对象原来指向的那块动态分配的空间释放了。
上面的代码还有一句:
//cout << *ap1 << endl;//报错
为什么报错??
这是因为ap1已经把它指向的空间交给了ap2去管理,所以ap1已经不具备访问原来自己所指向的空间的权限。所以对它进行解引用是非法的。
所以可以看清auto_ptr的本质是管理权的转移,即ap1将自己所指向的空间交给ap2来管理,析构也是由ap2来完成。
scoped_ptr
由于auto_ptr的严重缺陷,所以后来引入了scoped_ptr。防拷贝,意思就是不能进行拷贝,简单地说是一种简单粗暴的方式。模拟实现
template<class T> class Scopedptr { public: Scopedptr(T* ptr = NULL) :_ptr(ptr) {} T* operator->() { return _ptr; } T operator*() { return *_ptr; } ~Scopedptr() { delete _ptr; _ptr = NULL; } protected: Scopedptr(Scopedptr<T>& sp); Scopedptr<T>& operator=(const Scopedptr<T>& p); private: T* _ptr; }; void SPTest() { Scopedptr<int> sp(new int(10)); cout << "sp = " << *sp << endl; }
scoped_ptr中对拷贝构造函数和赋值运算符的重载函数只是进行了声明,并没有去定义这两个函数,而且声明为protected或者是private,这是防止别人在类外对这两个函数进行定义。防止拷贝,所以说scope_dptr是一种简单粗暴的方式。
shared_ptr
编写程序往往要用到拷贝,这样scopedptr就不能起到相应的作用,所以便有了shared_ptr。shared_ptr->采用了引用计数,优点是功能强大,但是也有缺点,缺点是过于复杂,而且会引起循环引用。
template<class T> class Sharedptr { public: Sharedptr(T* ptr = NULL) c68b :_ptr(ptr) , pcount(0) { if (_ptr != NULL) pcount = new int(1); } Sharedptr(const Sharedptr<T>& sp) { _ptr = sp._ptr; pcount = sp.pcount; ++(*pcount); } Sharedptr<T>& operator=(const Sharedptr<T>& sp) { if (this != &sp) { if (_ptr && --(*pcount) == 0) { delete pcount; delete _ptr; } pcount = sp.pcount; _ptr = sp._ptr; ++(*pcount); } return *this; } ~Sharedptr() { if (_ptr && --(*pcount) == 0) { delete _ptr; delete pcount; } } T& operator*() { return *_ptr; } T* operator->() { return _ptr; } T Getpcount() { return *(pcount); } void Realease() { if (--(*pcount) == 0) { delete _pcount; delete _ptr; } } void Reset(T* ptr, int* pcount) { if (_ptr != ptr) { delete _ptr; delete _pcount; } _ptr = ptr; _pcount = pcount; } private: T* _ptr; T* pcount; }; void Test() { Sharedptr<int> s1(new int(10)); cout << "s1 = " << *s1 << endl; cout << "pcount = " << s1.Getpcount() << endl; Sharedptr<int> s2(s1); cout << "s2 = " << *s2 << endl; cout << "pcount = " << s2.Getpcount() << endl; Sharedptr<int> s3; s3 = s1; cout << "s3 = " << *s3 << endl; cout << "pcount = " << s3.Getpcount() << endl; }
测试结果:
相关文章推荐
- C++智能指针(二)模拟实现三种智能指针
- C++ 智能指针的模拟实现实例
- 【C++】智能指针的作用,模拟实现auto_ptr,scoped_ptr,shared_ptr,scoped_array,shared_array
- 【C++】智能指针的作用,模拟实现auto_ptr,scoped_ptr,shared_ptr,scoped_array,shared_array
- 简单模拟实现c++智能指针-指针移交控制权
- C++中智能指针的实现
- **C++智能指针部分指针的实现**
- C++中智能指针的工作原理和简单实现
- [C++]智能指针的实现与使用
- C++智能指针shared_ptr的三种使用方式
- C++ 引用计数技术及智能指针的简单实现
- 用c++简单实现智能指针
- C++面试题(四)——智能指针的原理和实现
- 自己实现的C++智能指针的功能代码和测试用例
- C++中智能指针的工作原理和简单实现
- C++中智能指针的工作原理和简单实现
- 【转】C++ 引用计数技术及智能指针的简单实现
- c++实现引用计数智能指针
- C++ 智能指针——简单实现以及循环引用问题
- C++智能指针及其简单实现