c++智能指针(smart pointer)详解
来源:互联网 发布:tomcat启动源码 编辑:程序博客网 时间:2024/06/06 10:12
Smart Pointer
Deal with c++11’s smart pointer facility.
brief
Smart pointers are class objects that behave like built-in pointers but also manage objects that you create with new so that you don’t have to worry about when and whether to delete them - the smart pointers automatically delete the
managed object for you at the appropriate time.
- shared_ptr
- weak_ptr
- unique_ptr
shared_ptr (共享指针)
- referenced-counted smart pointer
- Shared Ownership with shared_ptr
引用计数智能指针:可以和其他 boost::shared_ptr 类型的智能指针共享所有权。 在这种情况下,当引用对象的最后一个智能指针销毁后或者被重新赋值或者使用了reset(),对象才会被释放。多个shared_ptr对象可以拥有同一个对象。
在继承中的例子:
shared_ptr<Thing> base_ptr(new Thing(2)); shared_ptr<Food> derived_ptr; ///if static_cast<Derived* >(base_ptr.get()) is valid, then the following is valid: base_ptr->showID(); ///cast failed derived_ptr = static_pointer_cast<Food>(base_ptr); shared_ptr<Food> a(new Food);// a->showID(); derived_ptr->showID();
使用 make_shared 更加高效
There are actually two dynamic memory allocations that happen: one for the object itself from the new, and then a second for the manager object created by the shared_ptr constructor. Since memory allocations are slow, this means that creating a shared_ptr is slow relative to using either a raw pointer, or a so-called “intrusive” reference- counted smart pointer where the reference count is a member variable of the object. To address this problem, C++11 includes a function template make_shared that does a single memory allocation big enough to hold both the manager object and the new object, passing along any constructor parameters that you specify, and returns a shared_ptr of the specified type, which can then be used to initialize the shared_ptr that you are creating (with efficient move semantics).
shared_ptr<Thing> p(new Thing); // ouch - two allocations shared_ptr<Thing> p1(make_shared<Thing>()); // only one allocation!
注意
- 使用 share_ptr copy assignment 或者构造函数会使shared_ptr的引用计数加1
- 使用 reset() 成员函数可以使当前share_ptr为空,删除指向对象的指针
- 通过给share_ptr赋值 nullptr 可以达到第二条的效果
- 不允许原生指针与智能指针之间的直接赋值转换
- 不要直接从原生指针构造两个功能相同的smart pointer,否则会造成double-deletion错误
- 可以通过 get() 函数获得原生指针
- 在继承关系或者其他的转换时,可以使用
- static_pointer_cast
- dynamic_pointer_cast
- const_pointer_cast
weak_ptr
Weak pointers just “observe” the managed object; they don’t “keep it alive” or affect its lifetime. Unlike shared_ptrs, when the last weak_ptr goes out of scope or disappears, the pointed-to object can still exist because
the weak_ptrs do not affect the lifetime of the object - they have no ownership rights. But the weak_ptr can be used to determine whether the object exists, and to provide a shared_ptr that can be used to refer to it.
仅仅观察被管理的对象,对其生命周期不产生任何影响
1.weak_ptr build-in-pointer might zero.
void do_it(weak_ptr<Thing> wp){shared_ptr<Thing> sp = wp.lock();// get shared_ptr from weak_ptr if(sp) sp->defrangulate(); // tell the Thing to do something else cout << "The Thing is gone!" << endl;}
2.This approach is useful as a way to simply ask whether the pointed-to object still exists.
bool is_it_there(weak_ptr<Thing> wp) { if(wp.expired()) { cout << "The Thing is gone!" << endl; return false; } return true; }
3.if the weak_ptr is expired, an exception is thrown, of type
std::bad_weak_ptr.
void do_it(weak_ptr<Thing> wp){shared_ptr<Thing> sp(wp); // construct shared_ptr from weak_ptr // exception thrown if wp is expired, so if here, sp is good to go sp->defrangulate(); // tell the Thing to do something} try { do_it(wpx); } catch(bad_weak_ptr&) { cout << "A Thing (or something else) has disappeared!" << endl; }
4.inherit from enabled_shared_from_this\
否则会出现的错误 error:pointer being freed was not allocated
class Thing:public enable_shared_from_this<Thing>{public: int id;public: virtual void showID() const; Thing(); Thing(int _id); void foo();};void Thing::foo() { shared_ptr<Thing> t1 = shared_from_this(); t1->showID();}
公有继承enable_shared_from_this\ ,则Thing类有了一个weak_ptr 作为成员变量。当第一个shared_ptr创建时,从第一个shared_ptr中初始化该weak_ptr\,当需要一个指向this的share_ptr时调用shared_from_this()成员函数,返回一个由weak_prt\构造而来的shared_ptr\,使得返回的shared_ptr与第一次的shared_ptr是相同的 manage object.
注意
- weak_ptr 与 share_ptr 结合使用,仅通过从share_ptr的复制和赋值,或者来源与其他weak_ptr。
- lock() 函数检查weak_ptr指向的对象是否存在,如果不存在返回一个空的share_ptr,否则返回一个指向该对象的share_ptr.
- 不能使用给weak_ptr赋值nullptr的方式,只能通过reset()方法
- expired()函数返回weak_ptr是否为存在非空对象。
- 在构造函数中不可以使用shared_from_this
- 尽可能多的搭配使用share_ptr和weak_ptr,自动化内存管理。
unique_ptr
With a unique_ptr, you can point to an allocated object, and when the unique_ptr goes out of scope, the pointed-to object gets deleted, and
this happens regardless of how we leave the function, either by a return or an exception being thrown somewhere.
unique_ptr implements a unique ownership concept - an object can be owned by only one unique_ptr at a time - the opposite of shared ownership.
unique_ptr 隐式的删除了copy构造函数,和copy assignment操作符,不允许一个对象同时被多个unique_ptr拥有这恰恰与shared_ptr相反。
The unique ownership is enforced by disallowing (with =delete) copy construction and copy assignment.So unlike built-in pointers or shared_ptr, you can’t copy or assign a unique_ptr to another unique_ptr.
move semantics: the move constructor and move assignment operator are defined for unique_ptr so that they transfer ownership from the original owner to the new owner.
可以通过move构造函数和move assignment 操作符使得unique_ptr的所属权从原来的转移到新的。转移之后原来的unique_ptr不包含任何对象。
隐式的从右值转换
unique_ptr<Thing> create_Thing() { unique_ptr<Thing> local_ptr(new Thing); return local_ptr; // local_ptr will surrender ownership }void foo() { unique_ptr<Thing> p1(create_Thing()); // move ctor from returned rvalue // p1 now owns the Thing unique_ptr<Thing> p2; // default ctor'd; owns nothing p2 = create_Thing(); // move assignment from returned rvalue // p2 now owns the second Thing}
显式的使用move assignment 和 move construction进行转换
unique_ptr<Thing> p1(new Thing); // p1 owns the Thingunique_ptr<Thing> p2; // p2 owns nothing// invoke move assignment explicitlyp2 = std::move(p1); // now p2 owns it, p1 owns nothing// invoke move construction explicitlyunique_ptr<Thing> p3(std::move(p2)); // now p3 owns it, p2 and p1 own nothing
注意
- 通过reset()函数或者给unique_ptr赋值nullptr,可以手工的删除对象。
reference
c++11 smart pointer
- C++:智能指针(Smart Pointer)
- 【C++】智能指针(Smart Pointer)
- c++智能指针(smart pointer)详解
- Smart Pointer--智能指针
- 智能指针(smart pointer)
- 智能指针(smart pointer)
- 智能指针(Smart Pointer)
- 智能指针 smart pointer
- C++ 智能指针(Smart Pointer)
- C++ 智能指针(Smart Pointer)
- 理解智能指针(Smart Pointer)
- 智能指针(Smart Pointer) [一]
- 智能指针(smart pointer)
- COM智能指针(Smart Pointer)的陷阱
- 深度探索智能指针(Smart Pointer)
- 什么是智能指针 what is smart pointer
- 智能指针(Smart Pointer)的实现
- C++中的智能指针(Smart Pointer)
- 深入理解hibernate中的API
- hashmap 中hash函数h & (length-1)详解
- Kaggle学习(一):numpy基本函数使用
- 多工程目录的实现
- 搭建WebSocket服务器与客户端
- c++智能指针(smart pointer)详解
- java 解决图片防盗链
- PAT 1016 Phone Bills
- shell 脚本教程 入门级
- Longest Common Prefix
- Mac自定义Android ndk工具链toolchain
- 【matlab】GUI的handlevisibility属性
- Insert Image using Spring JdbcTemplate
- js知识点