出现智能指针的原因

用智能指针,把申请内存的工作都在接口内部实现并加以限制,把释放内存的工作交给智能指针。

常见的智能指针

1.你知道智能指针吗?智能指针的原理。
2.常用的智能指针。
3.智能指针的实现。

  1答案:智能指针是一个类,这个类的构造函数中传入一个普通指针,析构函数中释放传入的指针。智能指针的类都是栈上的对象,所以当函数(或程序)结束时会自动被释放,

2, 最常用的智能指针:

1)std::auto_ptr,有很多问题。 不支持复制(拷贝构造函数)和赋值(operator =),但复制或赋值的时候不会提示出错。因为不能被复制,所以不能被放入容器中。

2) C++11引入的unique_ptr(scoped_ptr), 也不支持复制和赋值,但比auto_ptr好,直接赋值会编译出错。实在想赋值的话,需要使用:std::move。

例如:

std::unique_ptr<int> p1(new int(5));
std::unique_ptr<int> p2 = p1; // 编译会出错
std::unique_ptr<int> p3 = std::move(p1); // 转移所有权, 现在那块内存归p3所有, p1成为无效的指针.

3)C++11或boost的shared_ptr,基于引用计数的智能指针。可随意赋值,直到内存的引用计数为0的时候这个内存会被释放。

4)C++11或boost的weak_ptr,弱引用。 引用计数有一个问题就是互相引用形成环,这样两个指针指向的内存都无法释放。需要手动打破循环引用或使用weak_ptr。顾名思义,weak_ptr是一个弱引用,只引用,不计数。如果一块内存被shared_ptr和weak_ptr同时引用,当所有shared_ptr析构了之后,不管还有没有weak_ptr引用该内存,内存也会被释放。所以weak_ptr不保证它指向的内存一定是有效的,在使用之前需要检查weak_ptr是否为空指针。

智能指针的实现

Autoptr

代码:

#pragmaoncetemplate<classT>classAutoptr{public:Autoptr():_ptr(NULL){}Autoptr(T*ptr):_ptr(ptr){}Autoptr(Autoptr<T>&a):_ptr(a._ptr){delete_ptr;a._ptr=NULL;}~Autoptr(){if(_ptr){delete_ptr;_ptr=NULL;}}Autoptr<T>&operator=(Autoptr<T>&a){if(this!=&a){delete_ptr;_ptr=a._ptr;a._ptr=NULL;}return*this;}T&operator*(){return*_ptr;}T*Getptr(){return_ptr;}protected:T*_ptr;};voidAutoptrtest(){int*a=newint(5);Autoptr<int>ap1(a);cout<<*ap1<<endl;cout<<ap1.Getptr()<<endl;Autoptr<int>ap2(ap1);cout<<*ap2<<endl;cout<<ap2.Getptr()<<endl;cout<<ap1.Getptr()<<endl;Autoptr<int>ap3;ap3=ap2;cout<<*ap3<<endl;cout<<ap3.Getptr()<<endl;cout<<ap2.Getptr()<<endl;}

Scopedptr

代码:

#pragmaoncetemplate<classT>classScopedptr{public:Scopedptr():_ptr(NULL){}Scopedptr(T*data):_ptr(data){}~Scopedptr(){if(_ptr){delete_ptr;_ptr=NULL;}}T&operator*(){return*_ptr;}T*Getptr(){return_ptr;}protected://加上protected可以防止使用者在类之外定义拷贝构造和运算符的重载函数Scopedptr<T>(constScopedptr<T>&sp);//不让使用者使用拷贝,可以防止拷贝,所以只声明不定义Scopedptr<T>&operator=(constScopedptr<T>&sp);private:T*_ptr;};voidScopedptrtest(){int*a=newint(5);Scopedptr<int>ap1(a);cout<<*ap1<<endl;cout<<ap1.Getptr()<<endl;/*Scopedptr<int>ap2(ap1);cout<<*ap2<<endl;Scopedptr<int>ap3;ap3=ap2;cout<<*ap3<<endl;cout<<ap3.Getptr()<<endl;cout<<ap2.Getptr()<<endl;*/}

Sharedptr

代码:

#pragmaoncetemplate<classT>classSharedptr{public:Sharedptr():_ptr(NULL),_pcount(newint(1)){}Sharedptr(T*ptr):_ptr(ptr),_pcount(newint(1)){}Sharedptr(constSharedptr<T>&sp):_ptr(sp._ptr),_pcount(sp._pcount){++(*_pcount);}~Sharedptr(){if(_ptr){if(--(*_pcount)==0){delete_ptr;delete_pcount;_ptr=NULL;_pcount=NULL;}_ptr=NULL;}}Sharedptr<T>&operator=(constSharedptr<T>&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;};voidSharedptrtest(){int*a=newint(5);Sharedptr<int>ap1(a);Sharedptr<int>ap2(ap1);Sharedptr<int>ap3;ap3=ap2;}