Directory
- C + + smart pointer, pointer container principle and simple implementation (Auto_ptr,scoped_ptr,ptr_vector).
- Auto_ptr
- Scoped_ptr
- Ptr_vector
C + + smart pointer, pointer container principle and simple implementation (Auto_ptr,scoped_ptr,ptr_vector). Preface
Recently write a Muduo asynchronous log touch a lot of smart pointers, but do not intend to use the boost library, have to mold one to use.
智能指针的本质即用栈上对象来管理堆上数据的生命周期.
The smart pointer itself is an object, it is created on the stack, the structure of the allocation of resources on the heap, the destruction of the time to release resources, so as to avoid the heap on the data resource leakage situation.
Overloading it with the * operator implements the same operation as a bare pointer.
Below is a look at the implementation code of several local smart pointer objects.
Auto_ptr
AUTO_PTR Features: Implement copy constructor, overload = operator, implement-I, * operator, so that it can be used like a normal pointer,
Secure transfer rights are also achieved through the release () and Reset () methods.
#ifndef _AUTO_PTR_HH#define _AUTO_PTR_HHtemplate<typename T>class auto_ptr{public: explicit auto_ptr(T* p = 0):m_ptr(p){printf("1\n"); } auto_ptr(auto_ptr& obj):m_ptr(obj.release()){printf("2\n"); } auto_ptr& operator=(auto_ptr& obj){printf("3\n"); reset(obj.release()); return *this; } ~auto_ptr(){printf("4\n"); delete m_ptr; } T* release(){ T* tmp = m_ptr; m_ptr = 0; return tmp; } void reset(T* p){ if(m_ptr != p) delete m_ptr; m_ptr = p; } T* get() const { return m_ptr; } T* operator->(){ return get(); } T& operator*(){ return *get(); } private: T* m_ptr;};#endif
Test code:
#include "ScopePtr.hh"#include "auto_ptr.hh"#include <stdio.h>class NonCopyable{protected: //构造函数可以被派生类调用,但不能直接构造对象 NonCopyable() {printf("Nocopy Constroctr\n");} ~NonCopyable() {printf("~Nocopy DeConstroctr\n");}private: NonCopyable(const NonCopyable &); const NonCopyable &operator=(const NonCopyable &);};class Test// : private NonCopyable{{public: Test(){printf("Constroctr\n");} ~Test(){printf("~DeConstroctr\n");}};int main(){ //scoped_ptr<Test> st(new Test); auto_ptr<Test> ap1(new Test); auto_ptr<Test> ap2(new Test); auto_ptr<Test> ap3(ap2); ap2 = ap3; getchar(); return 0;}
Constroctr1Constroctr12344~DeConstroctr4~DeConstroctr
Scoped_ptr
This is what's in the Boost library, and it's the opposite of auto_ptr: the copy construction and the = overload are configured as private, which is not allowed to transfer ownership.
#ifndef _scope_ptr_hh#define _scope_ptr_hh//scoped_ptr mimics a built-in pointer except that it guarantees deletion//O F The object pointed to, either in destruction of the Scoped_ptr or via//an explicit reset (). Scoped_ptr is a simple solution for simple needs;//use shared_ptr or std::auto_ptr if your needs was more COMPLEX./*SCOP Ed_ptr is a local smart pointer that does not allow transfer of ownership. */template <class t>class scoped_ptr{public:scoped_ptr (T *p = 0): m_ptr (P) {} ~scoped_ptr () {D Elete M_ptr; } t&operator* () const {return *m_ptr; } t*operator-> () const {return m_ptr; } void Reset (T *p)//ownership is not allowed but allows the smart pointer to point to another space {if (P! = m_ptr && m_ptr! = 0) delet e m_ptr; M_ptr = p; } t* get () {return m_ptr; }private://the copy construction and assignment, and the sentencing inequality are set to private methods//objects can no longer be called, that is, the construction and assignment can not be copied to achieve the purpose of not transferring ownership scoped_ptr (const scoped_ptr<t> &A Mp;y); Scoped_ptr<t> operator= (const scoped_ptr<t>&); void operator== (scoped_ptr<t> const &) const; void operator!= (scoped_ptr<t> const &) const; T* m_ptr;}; #endif
Ptr_vector
This is also the boost inside the thing, if we put the object pointer to the vector inside, the container when the destruction of the structure of the space, although it will be opened up to the storage of pointers, but will not be able to analyze the pointer itself point to the space, so there is this container.
#ifndef _ptr_vector_hh#define _ptr_vector_hh#include "auto_ptr.hh" #include <vector>template<typename T> Class Ptr_vector:public Std::vector<t*>{public: ~ptr_vector () {clear (); } void Clear () {typename Std::vector<t*>::iterator it; for (it = Std::vector<t*>::begin (); It! = Std::vector<t*>::end (); ++it) {Delete *it;//releases the memory pointed to by the pointer. }/* for (size_t i = 0; i < std::vector<t*>::size (); ++i) {Delete Std::vecto R<t*>::back (); }*/std::vector<t*>::clear (); Releases the pointer itself. } TypeName Std::vector<t*>::iterator Erase (TypeName Std::vector<t*>::iterator it) {if (it >= std:: Vector<t*>::begin () && it < Std::vector<t*>::end ()) {delete *it; Std::vector<t*>::erase (IT); }} void Pop_back () {if (std::vector<t*>::size () > 0) {delete std::vector&Lt T*>::back (); Std::vector<t*>::p op_back (); }} void Push_back (t* const &V) {auto_ptr<t> ap (v); Std::vector<t*>::p ush_back (v); Ap.release (); } void Push_back (Auto_ptr<t> &v) {std::vector<t*>::p ush_back (V.get ()); V.release (); }}; #endif
Test code:
class Test// : private NonCopyable{{public: Test(int a = 99):a(a){printf("Constroctr\n");} ~Test(){printf("~DeConstroctr\n");} int get(){return a;}private: int a;};int main(){ auto_ptr<Test> ap1(new Test(0)); auto_ptr<Test> ap2(new Test(1)); auto_ptr<Test> ap3(new Test(2)); printf("%d\n", ap1->get()); ptr_vector<Test> apv; apv.push_back(ap1); apv.push_back(ap2); apv.push_back(ap3); printf("%d %lu \n", apv.front()->get(),apv.size());/* apv.pop_back(); printf("%lu\n", apv.size()); apv.pop_back(); printf("%lu\n", apv.size()); apv.pop_back(); printf("%lu\n", apv.size());*/ apv.pop_back(); printf("%lu\n", apv.size()); ptr_vector<Test>::iterator it = apv.begin(); apv.erase(it); printf("%lu\n", apv.size()); getchar(); return 0;}
ConstroctrConstroctrConstroctr00 3 ~DeConstroctr2~DeConstroctr1~DeConstroctr
This paper introduces the essence of smart pointers and the implementation of two simple smart pointers and a pointer container.
In fact, now auto_ptr use not much, if not the original passed in the hands of processing, transfer, the original pointer is empty, if someone to use will cause problems.
Vector also has a lot of problems, pop_back () An empty container, vector inside will do--size, this time the size of the container from 0 to infinity, the consequences can not be predicted. This is handled in this case. Pop_back () An empty vector will do nothing. But vector usage is still fastidious, otherwise it is easy to cause problems.
C + + smart pointer, pointer container principle and simple implementation (Auto_ptr,scoped_ptr,ptr_vector).