std::auto_ptr<MyObject> p1 (new MyObject());std::auto_ptr<MyObject> p2 = p1; // Copy and transfer ownership.// p1 gets set to empty!p2->DoSomething(); // Works.p1->DoSomething(); // Oh oh. Hopefully raises some NULL pointer exception.
// Need to create the object to achieve some goalMyObject* ptr = new MyObject();ptr->DoSomething(); // Use the object in some waydelete ptr; // Destroy the object. Done with it.// Wait, what if DoSomething() raises an exception...?
相比之下,智能指针定义了一个关于何时销毁对象的策略。您仍然需要创建对象,但您不再需要担心销毁它。
SomeSmartPtr<MyObject> ptr(new MyObject());ptr->DoSomething(); // Use the object in some way.
// Destruction of the object happens, depending// on the policy the smart pointer class uses.
// Destruction would happen even if DoSomething()// raises an exception
void f()\{\{std::unique_ptr<MyObject> ptr(new MyObject());ptr->DoSomethingUseful();} // ptr goes out of scope --// the MyObject is automatically destroyed.
// ptr->Oops(); // Compile error: "ptr" not defined// since it is no longer in scope.}
void f(){typedef std::shared_ptr<MyObject> MyObjectPtr; // nice short aliasMyObjectPtr p1; // Empty
{MyObjectPtr p2(new MyObject());// There is now one "reference" to the created objectp1 = p2; // Copy the pointer.// There are now two references to the object.} // p2 is destroyed, leaving one reference to the object.} // p1 is destroyed, leaving a reference count of zero.// The object is deleted.
当对象的生命周期要复杂得多,并且不直接绑定到特定的代码部分或另一个对象时,引用计数指针非常有用。
引用计数指针有一个缺点-创建悬空引用的可能性:
// Create the smart pointer on the heapMyObjectPtr* pp = new MyObjectPtr(new MyObject())// Hmm, we forgot to destroy the smart pointer,// because of that, the object is never destroyed!
另一种可能性是创建循环引用:
struct Owner {std::shared_ptr<Owner> other;};
std::shared_ptr<Owner> p1 (new Owner());std::shared_ptr<Owner> p2 (new Owner());p1->other = p2; // p1 references p2p2->other = p1; // p2 references p1
// Oops, the reference count of of p1 and p2 never goes to zero!// The objects are never destroyed!
T a ;//shared_ptr<T> shptr(new T) ; not recommended but worksshared_ptr<T> shptr = make_shared<T>(); // faster + exception safe
std::cout << shptr.use_count() ; // 1 // gives the number of "things " pointing to it.T * temp = shptr.get(); // gives a pointer to object
// shared_pointer used like a regular pointer to call member functionsshptr->memFn();(*shptr).memFn();
//shptr.reset() ; // frees the object pointed to be the ptrshptr = nullptr ; // frees the objectshptr = make_shared<T>() ; // frees the original object and points to new object
T a ;shared_ptr<T> shr = make_shared<T>() ;weak_ptr<T> wk = shr ; // initialize a weak_ptr from a shared_ptrwk.lock()->memFn() ; // use lock to get a shared_ptr// ^^^ Can lead to exception if the shared ptr has gone out of scopeif(!wk.expired()) wk.lock()->memFn() ;// Check if shared ptr has gone out of scope before access
unique_ptr<T> uptr(new T);uptr->memFn();
//T * ptr = uptr.release(); // uptr becomes null and object is pointed to by ptruptr.reset() ; // deletes the object pointed to by uptr
要更改唯一ptr指向的对象,请使用移动语义学
unique_ptr<T> uptr1(new T);unique_ptr<T> uptr2(new T);uptr2 = std::move(uptr1);// object pointed by uptr2 is deleted and// object pointed by uptr1 is pointed to by uptr2// uptr1 becomes null
r-value reference : reference to a temporary objectl-value reference : reference to an object whose address can be obtainedconst reference : reference to a data type which is const and cannot be modified
RAII: Resource Acquisition Is Initialization.
● When you initialize an object, it should already haveacquired any resources it needs (in the constructor).
● When an object goes out of scope, it should release everyresource it is using (using the destructor).
关键点:
● There should never be a half-ready or half-dead object.● When an object is created, it should be in a ready state.● When an object goes out of scope, it should release its resources.● The user shouldn’t have to do anything more.
原始指针违反RAII:当指针超出范围时,需要用户手动删除。
RAII解决方案是:
Have a smart pointer class:● Allocates the memory when initialized● Frees the memory when destructor is called● Allows access to underlying pointer
对于需要复制和共享的智能指针,使用shared_ptr:
● use another memory to store Reference counting and shared.● increment when copy, decrement when destructor.● delete memory when Reference counting is 0.also delete memory that store Reference counting.
对于智能指针不拥有原始指针,请使用weak_ptr:
● not change Reference counting.
shared_ptr用法:
correct way:std::shared_ptr<T> t1 = std::make_shared<T>(TArgs);std::shared_ptr<T> t2 = std::shared_ptr<T>(new T(Targs));
wrong way:T* pt = new T(TArgs); // never exposure the raw pointershared_ptr<T> t1 = shared_ptr<T>(pt);shared_ptr<T> t2 = shared_ptr<T>(pt);
T* pt; is optional reference and maybe nullptr.Not own the raw pointer,Raw pointer is managed by some one else.I only know that the caller is sure it is not released now.