C++在设计和使用智能指针

Fidelia ·
更新时间:2024-09-20
· 557 次阅读

  为一个C++用户的。使用指针可以算的上是常态,但在使用过程中。多的时间,可能是由于new要么malloc对象,上次忘记的释放结束(我会犯这样一个错误)内存泄露。   而此时智能指针可能能够帮助我去解决问题。   智能指针(smart pointer)是利用个引用计数的策略去处理指针的释放,从而保证指针的安全性。   通常情况下,我们会自己去设计一个智能指针类去管理自己的指针对象。   事实上其原理是存储指向动态分配的指针对象类。通过引用计数的功能去控制,去正确的实现指针对象的销毁,从而避免内存泄露。   智能指针的原理是。通过将指针类和一个引用计数关联起来,而引用计数计算,当前指针被多少个对象所共享。   每次创建一个新的指针对象的时候,初始化指针并将引用计数置为1;当对象作为还有一个对象的副本而被创建的时候。拷贝构造函数拷贝指针并添加与之相应的引用计数。对于一个对象进行赋值时。赋值操作符降低左操作数所指对象的引用计数(假设引用计数为减至0,则删除对象),而且添加右操作数所指对象的引用计数;调用析构函数时。构造函数降低引用计数(假设引用计数减至0,删除基础对象)。   以下的代码主要是借鉴了百度百科的代码来学习智能指针: #include<iostream> #include<stdexcept> using namespace std; #define TEST_SMARTPTR class Stub { public: void print(){ cout<<"Stub:print"<<endl; } ~Stub(){ cout<<"Stub:Destructor"<<endl; } }; template<typename T> class SmartPtr { public: SmartPtr(T*p=0):ptr(p),pUse(new size_t(1)){} SmartPtr(const SmartPtr& src):ptr(src.ptr),pUse(src.pUse){ ++*pUse; } SmartPtr&operator=(const SmartPtr& rhs){ //self-assigningisalsoright ++*rhs.pUse; decrUse(); ptr=rhs.ptr; pUse=rhs.pUse; return *this; } T* operator->(){ if(ptr) return ptr; throw std::runtime_error("accessthroughNULLpointer"); } const T* operator->()const{ if(ptr) return ptr; throw std::runtime_error("accessthroughNULLpointer"); } T &operator*(){ if(ptr) return *ptr; throw std::runtime_error("dereferenceofNULLpointer"); } const T &operator*()const{ if(ptr) return *ptr; throw std::runtime_error("dereferenceofNULLpointer"); } ~SmartPtr(){ decrUse(); #ifdef TEST_SMARTPTR std::cout<<"SmartPtr:Destructor"<<std::endl;//fortesting #endif } private: void decrUse(){ if(--*pUse==0){ delete ptr; delete pUse; } } T* ptr; size_t* pUse; }; int main() { try{ SmartPtr<Stub> t; t->print(); }catch(const exception&err){ cout<<err.what()<<endl; } SmartPtr<Stub>t1(new Stub); SmartPtr<Stub>t2(t1); SmartPtr<Stub>t3(new Stub); t3=t2; t1->print(); (*t3).print(); return 0; }   在面的代码中,智能指针一般都会去重载->和*操作符,从而使其表现指针的表象,而且大家能够使用它像使用指针一样。   在函数析构的时候,我们会发现引用计数在当中所起到的作用,从而避免误操作早成指针提前释放。造成指针悬挂。或者释放不彻底,造成内存泄漏的问题。



C++ 指针 c+ 智能指针

需要 登录 后方可回复, 如果你还没有账号请 注册新账号