出现智能指针的原因
常见的智能指针
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
代码:
#pragma once template<class T> class Autoptr { 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; }; void Autoptrtest() { int *a = new int(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
代码:
#pragma once template<class T> class Scopedptr { 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>(const Scopedptr<T>&sp); //不让使用者使用拷贝,可以防止拷贝,所以只声明不定义 Scopedptr<T>& operator=(const Scopedptr<T>&sp); private: T *_ptr; }; void Scopedptrtest() { int *a = new int(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
代码:
#pragma once template<class T> class Sharedptr { public: Sharedptr() :_ptr(NULL) , _pcount(new int(1)) {} Sharedptr(T *ptr) :_ptr(ptr) , _pcount(new int(1)) {} Sharedptr(const Sharedptr<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=(const Sharedptr<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; }; void Sharedptrtest() { int *a = new int(5); Sharedptr<int> ap1(a); Sharedptr<int> ap2(ap1); Sharedptr<int> ap3; ap3 = ap2; }
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。