重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
智能指针的三种常见写法:
创新互联公司是一家专业提供科尔沁左翼企业网站建设,专注与成都网站设计、做网站、H5技术、小程序制作等业务。10年已为科尔沁左翼众多企业、政府机构等服务。创新互联专业网站制作公司优惠进行中。
一、最开始的原始写法,原始写法可以理解为指针转移的方法。
templateclass AutoPtr { public: AutoPtr() :_ptr(NULL) {} AutoPtr(T* ptr) :_ptr(ptr) {} ~AutoPtr() { if (_ptr) { delete _ptr; _ptr = NULL; } } AutoPtr (AutoPtr & ap) : _ptr(ap._ptr) { ap._ptr = NULL; } AutoPtr & operator = (AutoPtr & ap) { if (this != &ap) { delete _ptr; _ptr = ap._ptr; ap._ptr = NULL; } return *this; } T& operator*() { return *_ptr; } T* GerPtr() { return _ptr; } private: T* _ptr; };
二、演变为后来的scoped写法,又可以称作守卫写法。该写法相对于原始写法的优点在于不让使用拷贝构造和运算符的重载,这样就避免了深浅拷贝的指针问题。做法是把拷贝构造、运算符的重载定声明出来而不定义,并且用protected保护起来。scoped写法是引用的boost库。有兴趣的可以去了解一下这个东西,背后还是有很多故事的,在这我就不多说啦。
templateclass scopedPtr { public: scopedPtr() :_ptr(NULL) {} scopedPtr(T* ptr) :_ptr(ptr) {} ~scopedPtr() { if (_ptr) { delete _ptr; _ptr = NULL; } } T& operator*() { return *_ptr; } T* operator->() { return _ptr; } T* GetPtr() { return _ptr; } protected: //加上protected可以防止使用者在类之外定义拷贝构造和运算符的重载函数 scopedPtr (const scopedPtr & sp); //不让使用者使用拷贝,可以防止拷贝,所以只声明不定义 scopedPtr & operator=(const scopedPtr & sp); private: T* _ptr; };
三、sharedPtr写法
这种方法考虑了深浅拷贝问题并且引用了引用计数器来解决浅拷贝的问题,比较完善的实现了智能指针想要实现的功能。
templateclass SharePtr { public: SharePtr(T* ptr) :_ptr(ptr) , _pCount(new int(1)) {} //SharePtr(Shar) // :_ptr(sp._ptr) //{ // *_pCount = 1; //} ~SharePtr() { if (_ptr) { if (--(*_pCount) == 0) { delete _ptr; delete _pCount; _ptr = NULL; _pCount = NULL; } _ptr = NULL; } } SharePtr (const SharePtr & sp) { _ptr = sp._ptr; _pCount = sp._pCount; ++(*_pCount); } SharePtr & operator=(const SharePtr & sp) { if (this != &sp) { if (--(*_pCount) == 0) //这里要分清楚是谁减一,逻辑需要分析清楚 { delete _ptr; delete _pCount; _ptr = NULL; _pCount = NULL; } _ptr = sp._ptr; _pCount = sp._pCount; ++(*_pCount); } return *this; } private: T* _ptr; int* _pCount; };