zoukankan      html  css  js  c++  java
  • C++在设计和使用智能指针

    为一个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;
    }
    在面的代码中,智能指针一般都会去重载->和*操作符,从而使其表现指针的表象,而且大家能够使用它像使用指针一样。

    在函数析构的时候,我们会发现引用计数在当中所起到的作用,从而避免误操作早成指针提前释放。造成指针悬挂。或者释放不彻底,造成内存泄漏的问题。

    版权声明:本文博客原创文章。博客,未经同意,不得转载。

  • 相关阅读:
    (转)R空间数据处理与可视化
    shell 脚本 exit 1 报错:numeric argument required问题解决
    如何在java中拟合正态分布
    Geometry关系高级操作
    IntelliJ IDEA 15.0.2远程debug tomcat
    jmc远程监控java服务
    Cannot assign requested address出现的原因及解决方案
    网络调试工具
    性能优化工具---sar
    性能优化工具---iostat
  • 原文地址:https://www.cnblogs.com/yxwkf/p/4731869.html
Copyright © 2011-2022 走看看