C++智能指针unique_ptr
C++11:unique_ptr、shared_ptr、weak_ptr,本节介绍一下unique_ptr 1.智能指针产生原因众所周知,C++程序设计中使用堆内存是非常频繁的操作,堆内存的申请和释放都由程序员自己管理。然而,很多程序员在使用堆内存时都很头疼,因为一次不恰当的使用方法,很容易造成堆内存泄露(忘记释放),二次释放,程序发生异常时内存泄露等问题等。所以C++引入了智能指针,使用使用智能指针能更好的管理堆内存。 2.理解智能指针原理1)智能指针是利用了一种叫做RAII技术对普通的指针进行封装,这使得智能指针实质是一个对象,行为表现的却像一个指针。 补充:RAII技术即资源分配及初始化,使用类来封装资源的分配和初始化,构造函数完成资源的分配和初始化,析构函数完成资源的清理,可以保证正确的初始化和资源释放。 2)智能指针是一个类,这个类的构造函数中传入一个普通指针,析构函数中释放传入的指针。智能指针的类都是栈上的对象,所以当函数(或程序)结束时会自动被释放。智能指针的作用是防止忘记调用delete释放内存和程序异常的进入catch块忘记释放内存。另外指针的释放时机也是非常有考究的,多次释放同一个指针会造成程序崩溃,这些都可以通过智能指针来解决。千万不要用一块非new分配的动态内存去初始化一个智能指针,因为自行释放非堆地址很有可能出现问题。 3)智能指针还有一个作用是把值语义转换成引用语义。 C++和Java有一处最大的区别在于语义不同,在Java里面,下列代码:? Student s1?= new Student (); Student s2?= s1; ?这里其实只生成了一个对象,s1和s2仅仅是共享对象的引用而已。但在C++中不是这样的, ? Student s1; ? Student s2?= s1; ? 这里却是就是生成了两个对象。 3.包含头文件C++98版的auto_ptr和C++11版的unique_ptr、shared_ptr、weak_ptr,都包含在头文件 4.unique_ptrunique_ptr持有对对象的独有权——两个unique_ptr不能指向一个对象,不能进行复制操作只能进行移动操作。但支持通过std::move转移内部指针所有权。 unique_ptr的成员函数: 1)get 获得内部对象的指针,由于已经重载了()方法,因此和直接使用对象是一样的.如 unique_ptr 2)release 放弃内部对象的所有权,将内部指针置为空,返回所内部对象的指针,此指针需要手动释放; 3)reset 销毁内部对象并接受新的对象的所有权(如果使用缺省参数的话,也就是没有任何对象的所有权,此时仅将内部对象释放,并置为空); unique_ptr up1 = nullptr; //显式销毁所指对象,同时智能指针变为空指针。与u_s2.reset()等价 4)swap 交换两个unique_ptr对象(即交换所拥有的对象); unique_ptr的用法: 1)unique_ptr对象不能进行拷贝和赋值操作,只能进行移动操作 unique_ptr unique_ptr unique_ptr unique_ptr 查看拷贝构造和赋值源码,可以看到它们都被标记为已删除的函数了,在编译上面的代码时,会报编译错误: unique_ptr(const _Myt&) = delete; _Myt& operator=(const _Myt&) = delete; 当然,有些博主解释为,它们被设成了不可访问的私有函数。? 虽然 unique_ptr 不支持拷贝和赋值,但是可以调用 release 或 reset 将指针的所有权从一个(非 const) unique_ptr 转移到另一个。 std::unique_ptr std::unique_ptr std::unique_ptr up3.reset(up2.release()); //up3销毁内部对象,并接受新的对象的所有权 2)源unique_ptr是临时右值时,编译器允许将源unique_ptr临时右值赋给另一个unique_ptr对象 // 可以进行移动构造 template std::unique_ptr { std::unique_ptr return temp; // 对象的所有权被传递出Clone() } unique_ptr unique_ptr pu2 = pu1; // pu1不是临时右值,编译器不允许 unique_ptr pu3 = unique_ptr 应该是编译器知道要临时右值的unique_ptr对象即将被销毁,因此执行一种特殊的"拷贝"。 3)两个unique_ptr不能指向一个对象 int *iPtr = new int(0); std::unique_ptr std::unique_ptr up2和up1都指向了iPtr,将来iPtr会被释放两次,造成错误。 4)unique_ptr支持管理动态数组 因为unique_ptr有unique_ptr unique_ptr p[0] = 0;// 重载了operator[] 5)容器 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |