- 1.往期回顾
- 2.auto_ptr的缺陷
- 1.缺陷一
- 2.缺陷二
- 3.unique_ptr
- 1."更安全的赋值"
- 2.支持创建动态数组
- 3.补充API
- 4.后续篇章
C++智能指针总结一——auto_ptr
2.auto_ptr的缺陷 1.缺陷一先来看下面的代码:
#include#include #include #include #include using namespace std; class DEMO { public: DEMO(int data) { this->data = data; cout << "创建text" << endl; cout << "data=" << data << endl; } ~DEMO() { cout << "析构text" << endl; cout << "data=" << data << endl; } private: int data; }; int main(void) { auto_ptr ptr(new int); auto_ptr ptr1(new DEMO(1)); auto_ptr ptr2(new DEMO(2)); cout << endl; cout << "ptr2=" << ptr2.get() << endl; //ptr2=ptr1之前 cout << "ptr1=" << ptr1.get() << endl; ptr2 = ptr1; //将ptr1赋值给ptr2 cout << "ptr2=" << ptr2.get() << endl; //ptr2=ptr1之后 cout << "ptr1=" << ptr1.get() << endl; system("pause"); return 0; }
运行结果如下图:
使用.get()方法获取智能指针绑定的动态内存首地址。
为什么会这样呢,这是因为auto_ptr具有排他所有权性,即一块动态内存只能被一个智能指针绑定,所以在执行ptr2=ptr1之后就相当于把ptr1绑定的动态内存交给ptr2控制,但ptr2之前绑定了动态内存,所以它会先把自己绑定的动态内存先释放(delete掉),然后绑定ptr1的动态内存,最后ptr1的内置指针变量被置为空指针。
这种行为其实是很奇怪的,因为在我们之前的语法中赋值 *** 作都不会产生如此怪异的行为。因此如果我们以往的思维方式去使用智能指针赋值 *** 作就很可能产生你无法轻易察觉的错误。
2.缺陷二不支持对象数组的内存管理
即不能使用auto_ptr指针分配数组,如:
3.unique_ptr 1.“更安全的赋值”由于auto_ptr存在的种种缺陷,C++11标准使用新的,更安全的unique_ptr取代auto_ptr。
unique_ptr具有与auto_ptr一样的排他所有权性,同一块动态内存也只允许一个智能指针对象绑定。
但是unique_ptr不允许这样的直接赋值。
只能这样使用:
加一个move相当于向编译器声明你知道这样 *** 作的风险和后果。实际上这样使用和auto_ptr的直接赋值也没有区别了,只是多了一个move提醒你自己智能指针赋值的特殊性。
#include#include #include #include #include using namespace std; int main(void) { unique_ptr ptr1(new int[5]); //分配动态数组 for (int count = 0; count < 5; ++count) { ptr1[count] = count; } for (int count = 0; count < 5; ++count) { cout << "ptr1[" << count << "]=" << ptr1[count] << endl; } system("pause"); return 0; }
结果:
3.补充API如 .release(),.reset() 方法和auto_ptr是一样的。详情可参考我的上一篇博文。这里主要讲一下新的。
.swap()方法:
#include#include #include #include #include using namespace std; int main(void) { unique_ptr ptr1(new int[5]); unique_ptr ptr2(new int[5]); cout << "ptr2=" << ptr2.get() << endl; cout << "ptr1=" << ptr1.get() << endl; ptr1.swap(ptr2); //交换两个智能指针绑定的动态内存 cout << endl; cout << "ptr2=" << ptr2.get() << endl; cout << "ptr1=" << ptr1.get() << endl; system("pause"); return 0; }
结果:
功能即交换两个智能指针绑定的动态内存。
主动释放对象:
#include#include #include #include #include using namespace std; int main(void) { unique_ptr ptr1(new int[5]); unique_ptr ptr2(new int[5]); cout << "ptr2=" << ptr2.get() << endl; cout << "ptr1=" << ptr1.get() << endl; ptr1 = nullptr; ptr2 = NULL; cout << "ptr2=" << ptr2.get() << endl; cout << "ptr1=" << ptr1.get() << endl; system("pause"); return 0; }
结果:
底层源码:
unique_ptr& operator=(nullptr_t) noexcept { reset(); return *this; }
可以看到,unique_ptr重载了“=”号运算符,执行reset()函数,且注意到当reset()函数传入的参数为空时,参数默认初始化为nullptr,即能达到的效果为释放原先绑定的动态内存,再将对象指针赋值为nullptr。
reset()函数:
void reset(_Ty* _Ptr = nullptr) noexcept { // destroy designated object and store new pointer if (_Ptr != _Myptr) { delete _Myptr; } _Myptr = _Ptr; }4.后续篇章
C++智能指针总结三——shared_ptr与weak_ptr
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)