Differences between unique_ptr and shared_ptr [duplicate] - c++

This question already has answers here:
Closed 11 years ago.
Possible Duplicates:
pimpl: shared_ptr or unique_ptr
smart pointers (boost) explained
Could someone explain differences between shared_ptr and unique_ptr?

Both of these classes are smart pointers, which means that they automatically (in most cases) will deallocate the object that they point at when that object can no longer be referenced. The difference between the two is how many different pointers of each type can refer to a resource.
When using unique_ptr, there can be at most one unique_ptr pointing at any one resource. When that unique_ptr is destroyed, the resource is automatically reclaimed. Because there can only be one unique_ptr to any resource, any attempt to make a copy of a unique_ptr will cause a compile-time error. For example, this code is illegal:
unique_ptr<T> myPtr(new T); // Okay
unique_ptr<T> myOtherPtr = myPtr; // Error: Can't copy unique_ptr
However, unique_ptr can be moved using the new move semantics:
unique_ptr<T> myPtr(new T); // Okay
unique_ptr<T> myOtherPtr = std::move(myPtr); // Okay, resource now stored in myOtherPtr
Similarly, you can do something like this:
unique_ptr<T> MyFunction() {
unique_ptr<T> myPtr(/* ... */);
/* ... */
return myPtr;
}
This idiom means "I'm returning a managed resource to you. If you don't explicitly capture the return value, then the resource will be cleaned up. If you do, then you now have exclusive ownership of that resource." In this way, you can think of unique_ptr as a safer, better replacement for auto_ptr.
shared_ptr, on the other hand, allows for multiple pointers to point at a given resource. When the very last shared_ptr to a resource is destroyed, the resource will be deallocated. For example, this code is perfectly legal:
shared_ptr<T> myPtr(new T); // Okay
shared_ptr<T> myOtherPtr = myPtr; // Sure! Now have two pointers to the resource.
Internally, shared_ptr uses reference counting to track how many pointers refer to a resource, so you need to be careful not to introduce any reference cycles.
In short:
Use unique_ptr when you want a single pointer to an object that will be reclaimed when that single pointer is destroyed.
Use shared_ptr when you want multiple pointers to the same resource.

unique_ptr is the light-weight smart pointer of choice if you just have a dynamic object somewhere for which one consumer has sole (hence "unique") responsibility -- maybe a wrapper class that needs to maintain some dynamically allocated object. unique_ptr has very little overhead. It is not copyable, but movable. Its type is template <typename D, typename Deleter> class unique_ptr;, so it depends on two template parameters.
unique_ptr is also what auto_ptr wanted to be in the old C++ but couldn't because of that language's limitations.
shared_ptr on the other hand is a very different animal. The obvious difference is that you can have many consumers sharing responsibility for a dynamic object (hence "shared"), and the object will only be destroyed when all shared pointers have gone away. Additionally you can have observing weak pointers which will intelligently be informed if the shared pointer they're following has disappeared.
Internally, shared_ptr has a lot more going on: There is a reference count, which is updated atomically to allow the use in concurrent code. Also, there's plenty of allocation going on, one for an internal bookkeeping "reference control block", and another (often) for the actual member object.
But there's another big difference: The shared pointers type is always template <typename T> class shared_ptr;, and this is despite the fact that you can initialize it with custom deleters and with custom allocators. The deleter and allocator are tracked using type erasure and virtual function dispatch, which adds to the internal weight of the class, but has the enormous advantage that different sorts of shared pointers of type T are all compatible, no matter the deletion and allocation details. Thus they truly express the concept of "shared responsibility for T" without burdening the consumer with the details!
Both shared_ptr and unique_ptr are designed to be passed by value (with the obvious movability requirement for the unique pointer). Neither should make you worried about the overhead, since their power is truly astounding, but if you have a choice, prefer unique_ptr, and only use shared_ptr if you really need shared responsibility.

unique_ptr
is a smart pointer which owns an object exclusively.
shared_ptr
is a smart pointer for shared ownership. It is both copyable and movable. Multiple smart pointer instances can own the same resource. As soon as the last smart pointer owning the resource goes out of scope, the resource will be freed.

When wrapping a pointer in a unique_ptr you cannot have multiple copies of unique_ptr. The shared_ptr holds a reference counter which count the number of copies of the stored pointer. Each time a shared_ptr is copied, this counter is incremented. Each time a shared_ptr is destructed, this counter is decremented. When this counter reaches 0, then the stored object is destroyed.

Related

What is the modern and safe way to write destructor for class that contains member struct? [duplicate]

What is a smart pointer and when should I use one?
UPDATE
This answer is rather old, and so describes what was 'good' at the time, which was smart pointers provided by the Boost library. Since C++11, the standard library has provided sufficient smart pointers types, and so you should favour the use of std::unique_ptr, std::shared_ptr and std::weak_ptr.
There was also std::auto_ptr. It was very much like a scoped pointer, except that it also had the "special" dangerous ability to be copied — which also unexpectedly transfers ownership.
It was deprecated in C++11 and removed in C++17, so you shouldn't use it.
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.
OLD ANSWER
A smart pointer is a class that wraps a 'raw' (or 'bare') C++ pointer, to manage the lifetime of the object being pointed to. There is no single smart pointer type, but all of them try to abstract a raw pointer in a practical way.
Smart pointers should be preferred over raw pointers. If you feel you need to use pointers (first consider if you really do), you would normally want to use a smart pointer as this can alleviate many of the problems with raw pointers, mainly forgetting to delete the object and leaking memory.
With raw pointers, the programmer has to explicitly destroy the object when it is no longer useful.
// Need to create the object to achieve some goal
MyObject* ptr = new MyObject();
ptr->DoSomething(); // Use the object in some way
delete ptr; // Destroy the object. Done with it.
// Wait, what if DoSomething() raises an exception...?
A smart pointer by comparison defines a policy as to when the object is destroyed. You still have to create the object, but you no longer have to worry about destroying it.
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
The simplest policy in use involves the scope of the smart pointer wrapper object, such as implemented by boost::scoped_ptr or std::unique_ptr.
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.
}
Note that std::unique_ptr instances cannot be copied. This prevents the pointer from being deleted multiple times (incorrectly). You can, however, pass references to it around to other functions you call.
std::unique_ptrs are useful when you want to tie the lifetime of the object to a particular block of code, or if you embedded it as member data inside another object, the lifetime of that other object. The object exists until the containing block of code is exited, or until the containing object is itself destroyed.
A more complex smart pointer policy involves reference counting the pointer. This does allow the pointer to be copied. When the last "reference" to the object is destroyed, the object is deleted. This policy is implemented by boost::shared_ptr and std::shared_ptr.
void f()
{
typedef std::shared_ptr<MyObject> MyObjectPtr; // nice short alias
MyObjectPtr p1; // Empty
{
MyObjectPtr p2(new MyObject());
// There is now one "reference" to the created object
p1 = 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.
Reference counted pointers are very useful when the lifetime of your object is much more complicated, and is not tied directly to a particular section of code or to another object.
There is one drawback to reference counted pointers — the possibility of creating a dangling reference:
// Create the smart pointer on the heap
MyObjectPtr* pp = new MyObjectPtr(new MyObject())
// Hmm, we forgot to destroy the smart pointer,
// because of that, the object is never destroyed!
Another possibility is creating circular references:
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 p2
p2->other = p1; // p2 references p1
// Oops, the reference count of of p1 and p2 never goes to zero!
// The objects are never destroyed!
To work around this problem, both Boost and C++11 have defined a weak_ptr to define a weak (uncounted) reference to a shared_ptr.
Here's a simple answer for these days of modern C++ (C++11 and later):
"What is a smart pointer?"
It's a type whose values can be used like pointers, but which provides the additional feature of automatic memory management: When a smart pointer is no longer in use, the memory it points to is deallocated (see also the more detailed definition on Wikipedia).
"When should I use one?"
In code which involves tracking the ownership of a piece of memory, allocating or de-allocating; the smart pointer often saves you the need to do these things explicitly.
"But which smart pointer should I use in which of those cases?"
Use std::unique_ptr when you want your object to live just as long as a single owning reference to it lives. For example, use it for a pointer to memory which gets allocated on entering some scope and de-allocated on exiting the scope.
Use std::shared_ptr when you do want to refer to your object from multiple places - and do not want your object to be de-allocated until all these references are themselves gone.
Use std::weak_ptr when you do want to refer to your object from multiple places - for those references for which it's ok to ignore and deallocate (so they'll just note the object is gone when you try to dereference).
There is a proposal to add hazard pointers to C++26, but for now you don't have them.
Don't use the boost:: smart pointers or std::auto_ptr except in special cases which you can read up on if you must.
"Hey, I didn't ask which one to use!"
Ah, but you really wanted to, admit it.
"So when should I use regular pointers then?"
Mostly in code that is oblivious to memory ownership. This would typically be in functions which get a pointer from someplace else and do not allocate nor de-allocate, and do not store a copy of the pointer which outlasts their execution.
UPDATE:
This answer is outdated concerning C++ types which were used in the past.
std::auto_ptr is deprecated and removed in new standards.
Instead of boost::shared_ptr the std::shared_ptr should be used which is part of the standard.
The links to the concepts behind the rationale of smart pointers still mostly relevant.
Modern C++ has the following smart pointer types and doesn't require boost smart pointers:
std::shared_ptr
std::weak_ptr
std::unique_ptr
There is also 2-nd edition of the book mentioned in the answer: C++ Templates: The Complete Guide 2nd Edition by David Vandevoorde Nicolai, M. Josuttis, Douglas Gregor
OLD ANSWER:
A smart pointer is a pointer-like type with some additional functionality, e.g. automatic memory deallocation, reference counting etc.
A small intro is available on the page Smart Pointers - What, Why, Which?.
One of the simple smart-pointer types is std::auto_ptr (chapter 20.4.5 of C++ standard), which allows one to deallocate memory automatically when it out of scope and which is more robust than simple pointer usage when exceptions are thrown, although less flexible.
Another convenient type is boost::shared_ptr which implements reference counting and automatically deallocates memory when no references to the object remains. This helps avoiding memory leaks and is easy to use to implement RAII.
The subject is covered in depth in book "C++ Templates: The Complete Guide" by David Vandevoorde, Nicolai M. Josuttis, chapter Chapter 20. Smart Pointers.
Some topics covered:
Protecting Against Exceptions
Holders, (note, std::auto_ptr is implementation of such type of smart pointer)
Resource Acquisition Is Initialization (This is frequently used for exception-safe resource management in C++)
Holder Limitations
Reference Counting
Concurrent Counter Access
Destruction and Deallocation
Definitions provided by Chris, Sergdev and Llyod are correct. I prefer a simpler definition though, just to keep my life simple:
A smart pointer is simply a class that overloads the -> and * operators. Which means that your object semantically looks like a pointer but you can make it do way cooler things, including reference counting, automatic destruction etc.
shared_ptr and auto_ptr are sufficient in most cases, but come along with their own set of small idiosyncrasies.
A smart pointer is like a regular (typed) pointer, like "char*", except when the pointer itself goes out of scope then what it points to is deleted as well. You can use it like you would a regular pointer, by using "->", but not if you need an actual pointer to the data. For that, you can use "&*ptr".
It is useful for:
Objects that must be allocated with new, but that you'd like to have the same lifetime as something on that stack. If the object is assigned to a smart pointer, then they will be deleted when the program exits that function/block.
Data members of classes, so that when the object is deleted all the owned data is deleted as well, without any special code in the destructor (you will need to be sure the destructor is virtual, which is almost always a good thing to do).
You may not want to use a smart pointer when:
... the pointer shouldn't actually own the data... i.e., when you are just using the data, but you want it to survive the function where you are referencing it.
... the smart pointer isn't itself going to be destroyed at some point. You don't want it to sit in memory that never gets destroyed (such as in an object that is dynamically allocated but won't be explicitly deleted).
... two smart pointers might point to the same data. (There are, however, even smarter pointers that will handle that... that is called reference counting.)
See also:
garbage collection.
This stack overflow question regarding data ownership
A smart pointer is an object that acts like a pointer, but additionally provides control on construction, destruction, copying, moving and dereferencing.
One can implement one's own smart pointer, but many libraries also provide smart pointer implementations each with different advantages and drawbacks.
For example, Boost provides the following smart pointer implementations:
shared_ptr<T> is a pointer to T using a reference count to determine when the object is no longer needed.
scoped_ptr<T> is a pointer automatically deleted when it goes out of scope. No assignment is possible.
intrusive_ptr<T> is another reference counting pointer. It provides better performance than shared_ptr, but requires the type T to provide its own reference counting mechanism.
weak_ptr<T> is a weak pointer, working in conjunction with shared_ptr to avoid circular references.
shared_array<T> is like shared_ptr, but for arrays of T.
scoped_array<T> is like scoped_ptr, but for arrays of T.
These are just one linear descriptions of each and can be used as per need, for further detail and examples one can look at the documentation of Boost.
Additionally, the C++ standard library provides three smart pointers; std::unique_ptr for unique ownership, std::shared_ptr for shared ownership and std::weak_ptr. std::auto_ptr existed in C++03 but is now deprecated.
Most kinds of smart pointers handle disposing of the pointer-to object for you. It's very handy because you don't have to think about disposing of objects manually anymore.
The most commonly-used smart pointers are std::tr1::shared_ptr (or boost::shared_ptr), and, less commonly, std::auto_ptr. I recommend regular use of shared_ptr.
shared_ptr is very versatile and deals with a large variety of disposal scenarios, including cases where objects need to be "passed across DLL boundaries" (the common nightmare case if different libcs are used between your code and the DLLs).
Here is the Link for similar answers : http://sickprogrammersarea.blogspot.in/2014/03/technical-interview-questions-on-c_6.html
A smart pointer is an object that acts, looks and feels like a normal pointer but offers more functionality. In C++, smart pointers are implemented as template classes that encapsulate a pointer and override standard pointer operators. They have a number of advantages over regular pointers. They are guaranteed to be initialized as either null pointers or pointers to a heap object. Indirection through a null pointer is checked. No delete is ever necessary. Objects are automatically freed when the last pointer to them has gone away. One significant problem with these smart pointers is that unlike regular pointers, they don't respect inheritance. Smart pointers are unattractive for polymorphic code. Given below is an example for the implementation of smart pointers.
Example:
template <class X>
class smart_pointer
{
public:
smart_pointer(); // makes a null pointer
smart_pointer(const X& x) // makes pointer to copy of x
X& operator *( );
const X& operator*( ) const;
X* operator->() const;
smart_pointer(const smart_pointer <X> &);
const smart_pointer <X> & operator =(const smart_pointer<X>&);
~smart_pointer();
private:
//...
};
This class implement a smart pointer to an object of type X. The object itself is located on the heap. Here is how to use it:
smart_pointer <employee> p= employee("Harris",1333);
Like other overloaded operators, p will behave like a regular pointer,
cout<<*p;
p->raise_salary(0.5);
Let T be a class in this tutorial
Pointers in C++ can be divided into 3 types :
1) Raw pointers :
T a;
T * _ptr = &a;
They hold a memory address to a location in memory. Use with caution , as programs become complex hard to keep track.
Pointers with const data or address { Read backwards }
T a ;
const T * ptr1 = &a ;
T const * ptr1 = &a ;
Pointer to a data type T which is a const. Meaning you cannot change the data type using the pointer. ie *ptr1 = 19 ; will not work. But you can move the pointer. ie ptr1++ , ptr1-- ; etc will work.
Read backwards : pointer to type T which is const
T * const ptr2 ;
A const pointer to a data type T . Meaning you cannot move the pointer but you can change the value pointed to by the pointer. ie *ptr2 = 19 will work but ptr2++ ; ptr2-- etc will not work. Read backwards : const pointer to a type T
const T * const ptr3 ;
A const pointer to a const data type T . Meaning you cannot either move the pointer nor can you change the data type pointer to be the pointer. ie . ptr3-- ; ptr3++ ; *ptr3 = 19; will not work
3) Smart Pointers : { #include <memory> }
Shared Pointer:
T a ;
//shared_ptr<T> shptr(new T) ; not recommended but works
shared_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 functions
shptr->memFn();
(*shptr).memFn();
//
shptr.reset() ; // frees the object pointed to be the ptr
shptr = nullptr ; // frees the object
shptr = make_shared<T>() ; // frees the original object and points to new object
Implemented using reference counting to keep track of how many " things " point to the object pointed to by the pointer. When this count goes to 0 , the object is automatically deleted , ie objected is deleted when all the share_ptr pointing to the object goes out of scope.
This gets rid of the headache of having to delete objects which you have allocated using new.
Weak Pointer :
Helps deal with cyclic reference which arises when using Shared Pointer
If you have two objects pointed to by two shared pointers and there is an internal shared pointer pointing to each others shared pointer then there will be a cyclic reference and the object will not be deleted when shared pointers go out of scope. To solve this , change the internal member from a shared_ptr to weak_ptr. Note : To access the element pointed to by a weak pointer use lock() , this returns a weak_ptr.
T a ;
shared_ptr<T> shr = make_shared<T>() ;
weak_ptr<T> wk = shr ; // initialize a weak_ptr from a shared_ptr
wk.lock()->memFn() ; // use lock to get a shared_ptr
// ^^^ Can lead to exception if the shared ptr has gone out of scope
if(!wk.expired()) wk.lock()->memFn() ;
// Check if shared ptr has gone out of scope before access
See : When is std::weak_ptr useful?
Unique Pointer :
Light weight smart pointer with exclusive ownership. Use when pointer points to unique objects without sharing the objects between the pointers.
unique_ptr<T> uptr(new T);
uptr->memFn();
//T * ptr = uptr.release(); // uptr becomes null and object is pointed to by ptr
uptr.reset() ; // deletes the object pointed to by uptr
To change the object pointed to by the unique ptr , use move semantics
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
References :
They can essentially be though of as const pointers, ie a pointer which is const and cannot be moved with better syntax.
See : What are the differences between a pointer variable and a reference variable in C++?
r-value reference : reference to a temporary object
l-value reference : reference to an object whose address can be obtained
const reference : reference to a data type which is const and cannot be modified
Reference :
https://www.youtube.com/channel/UCEOGtxYTB6vo6MQ-WQ9W_nQ
Thanks to Andre for pointing out this question.
http://en.wikipedia.org/wiki/Smart_pointer
In computer science, a smart pointer
is an abstract data type that
simulates a pointer while providing
additional features, such as automatic
garbage collection or bounds checking.
These additional features are intended
to reduce bugs caused by the misuse of
pointers while retaining efficiency.
Smart pointers typically keep track of
the objects that point to them for the
purpose of memory management. The
misuse of pointers is a major source
of bugs: the constant allocation,
deallocation and referencing that must
be performed by a program written
using pointers makes it very likely
that some memory leaks will occur.
Smart pointers try to prevent memory
leaks by making the resource
deallocation automatic: when the
pointer to an object (or the last in a
series of pointers) is destroyed, for
example because it goes out of scope,
the pointed object is destroyed too.
A smart pointer is a class, a wrapper of a normal pointer. Unlike normal pointers, smart point’s life circle is based on a reference count (how many time the smart pointer object is assigned). So whenever a smart pointer is assigned to another one, the internal reference count plus plus. And whenever the object goes out of scope, the reference count minus minus.
Automatic pointer, though looks similar, is totally different from smart pointer. It is a convenient class that deallocates the resource whenever an automatic pointer object goes out of variable scope. To some extent, it makes a pointer (to dynamically allocated memory) works similar to a stack variable (statically allocated in compiling time).
What is a smart pointer.
Long version, In principle:
https://web.stanford.edu/class/archive/cs/cs106l/cs106l.1192/lectures/lecture15/15_RAII.pdf
A modern C++ idiom:
RAII: Resource Acquisition Is Initialization.
● When you initialize an object, it should already have
acquired any resources it needs (in the constructor).
● When an object goes out of scope, it should release every
resource it is using (using the destructor).
key point:
● 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.
Raw Pointers violate RAII: It need user to delete manually when the pointers go out of scope.
RAII solution is:
Have a smart pointer class:
● Allocates the memory when initialized
● Frees the memory when destructor is called
● Allows access to underlying pointer
For smart pointer need copy and share, use 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.
for smart pointer not own the raw pointer, use weak_ptr:
● not change Reference counting.
shared_ptr usage:
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 pointer
shared_ptr<T> t1 = shared_ptr<T>(pt);
shared_ptr<T> t2 = shared_ptr<T>(pt);
Always avoid using raw pointer.
For scenario that have to use raw pointer:
https://stackoverflow.com/a/19432062/2482283
For raw pointer that not nullptr, use reference instead.
not use T*
use T&
For optional reference which maybe nullptr, use raw pointer, and which means:
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.
Smart Pointers are those where you don't have to worry about Memory De-Allocation, Resource Sharing and Transfer.
You can very well use these pointer in the similar way as any allocation works in Java. In java Garbage Collector does the trick, while in Smart Pointers, the trick is done by Destructors.
The existing answers are good but don't cover what to do when a smart pointer is not the (complete) answer to the problem you are trying to solve.
Among other things (explained well in other answers) using a smart pointer is a possible solution to How do we use a abstract class as a function return type? which has been marked as a duplicate of this question. However, the first question to ask if tempted to specify an abstract (or in fact, any) base class as a return type in C++ is "what do you really mean?". There is a good discussion (with further references) of idiomatic object oriented programming in C++ (and how this is different to other languages) in the documentation of the boost pointer container library. In summary, in C++ you have to think about ownership. Which smart pointers help you with, but are not the only solution, or always a complete solution (they don't give you polymorphic copy) and are not always a solution you want to expose in your interface (and a function return sounds an awful lot like an interface). It might be sufficient to return a reference, for example. But in all of these cases (smart pointer, pointer container or simply returning a reference) you have changed the return from a value to some form of reference. If you really needed copy you may need to add more boilerplate "idiom" or move beyond idiomatic (or otherwise) OOP in C++ to more generic polymorphism using libraries like Adobe Poly or Boost.TypeErasure.

Free Allocated Memory in a Parameter [duplicate]

What is a smart pointer and when should I use one?
UPDATE
This answer is rather old, and so describes what was 'good' at the time, which was smart pointers provided by the Boost library. Since C++11, the standard library has provided sufficient smart pointers types, and so you should favour the use of std::unique_ptr, std::shared_ptr and std::weak_ptr.
There was also std::auto_ptr. It was very much like a scoped pointer, except that it also had the "special" dangerous ability to be copied — which also unexpectedly transfers ownership.
It was deprecated in C++11 and removed in C++17, so you shouldn't use it.
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.
OLD ANSWER
A smart pointer is a class that wraps a 'raw' (or 'bare') C++ pointer, to manage the lifetime of the object being pointed to. There is no single smart pointer type, but all of them try to abstract a raw pointer in a practical way.
Smart pointers should be preferred over raw pointers. If you feel you need to use pointers (first consider if you really do), you would normally want to use a smart pointer as this can alleviate many of the problems with raw pointers, mainly forgetting to delete the object and leaking memory.
With raw pointers, the programmer has to explicitly destroy the object when it is no longer useful.
// Need to create the object to achieve some goal
MyObject* ptr = new MyObject();
ptr->DoSomething(); // Use the object in some way
delete ptr; // Destroy the object. Done with it.
// Wait, what if DoSomething() raises an exception...?
A smart pointer by comparison defines a policy as to when the object is destroyed. You still have to create the object, but you no longer have to worry about destroying it.
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
The simplest policy in use involves the scope of the smart pointer wrapper object, such as implemented by boost::scoped_ptr or std::unique_ptr.
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.
}
Note that std::unique_ptr instances cannot be copied. This prevents the pointer from being deleted multiple times (incorrectly). You can, however, pass references to it around to other functions you call.
std::unique_ptrs are useful when you want to tie the lifetime of the object to a particular block of code, or if you embedded it as member data inside another object, the lifetime of that other object. The object exists until the containing block of code is exited, or until the containing object is itself destroyed.
A more complex smart pointer policy involves reference counting the pointer. This does allow the pointer to be copied. When the last "reference" to the object is destroyed, the object is deleted. This policy is implemented by boost::shared_ptr and std::shared_ptr.
void f()
{
typedef std::shared_ptr<MyObject> MyObjectPtr; // nice short alias
MyObjectPtr p1; // Empty
{
MyObjectPtr p2(new MyObject());
// There is now one "reference" to the created object
p1 = 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.
Reference counted pointers are very useful when the lifetime of your object is much more complicated, and is not tied directly to a particular section of code or to another object.
There is one drawback to reference counted pointers — the possibility of creating a dangling reference:
// Create the smart pointer on the heap
MyObjectPtr* pp = new MyObjectPtr(new MyObject())
// Hmm, we forgot to destroy the smart pointer,
// because of that, the object is never destroyed!
Another possibility is creating circular references:
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 p2
p2->other = p1; // p2 references p1
// Oops, the reference count of of p1 and p2 never goes to zero!
// The objects are never destroyed!
To work around this problem, both Boost and C++11 have defined a weak_ptr to define a weak (uncounted) reference to a shared_ptr.
Here's a simple answer for these days of modern C++ (C++11 and later):
"What is a smart pointer?"
It's a type whose values can be used like pointers, but which provides the additional feature of automatic memory management: When a smart pointer is no longer in use, the memory it points to is deallocated (see also the more detailed definition on Wikipedia).
"When should I use one?"
In code which involves tracking the ownership of a piece of memory, allocating or de-allocating; the smart pointer often saves you the need to do these things explicitly.
"But which smart pointer should I use in which of those cases?"
Use std::unique_ptr when you want your object to live just as long as a single owning reference to it lives. For example, use it for a pointer to memory which gets allocated on entering some scope and de-allocated on exiting the scope.
Use std::shared_ptr when you do want to refer to your object from multiple places - and do not want your object to be de-allocated until all these references are themselves gone.
Use std::weak_ptr when you do want to refer to your object from multiple places - for those references for which it's ok to ignore and deallocate (so they'll just note the object is gone when you try to dereference).
There is a proposal to add hazard pointers to C++26, but for now you don't have them.
Don't use the boost:: smart pointers or std::auto_ptr except in special cases which you can read up on if you must.
"Hey, I didn't ask which one to use!"
Ah, but you really wanted to, admit it.
"So when should I use regular pointers then?"
Mostly in code that is oblivious to memory ownership. This would typically be in functions which get a pointer from someplace else and do not allocate nor de-allocate, and do not store a copy of the pointer which outlasts their execution.
UPDATE:
This answer is outdated concerning C++ types which were used in the past.
std::auto_ptr is deprecated and removed in new standards.
Instead of boost::shared_ptr the std::shared_ptr should be used which is part of the standard.
The links to the concepts behind the rationale of smart pointers still mostly relevant.
Modern C++ has the following smart pointer types and doesn't require boost smart pointers:
std::shared_ptr
std::weak_ptr
std::unique_ptr
There is also 2-nd edition of the book mentioned in the answer: C++ Templates: The Complete Guide 2nd Edition by David Vandevoorde Nicolai, M. Josuttis, Douglas Gregor
OLD ANSWER:
A smart pointer is a pointer-like type with some additional functionality, e.g. automatic memory deallocation, reference counting etc.
A small intro is available on the page Smart Pointers - What, Why, Which?.
One of the simple smart-pointer types is std::auto_ptr (chapter 20.4.5 of C++ standard), which allows one to deallocate memory automatically when it out of scope and which is more robust than simple pointer usage when exceptions are thrown, although less flexible.
Another convenient type is boost::shared_ptr which implements reference counting and automatically deallocates memory when no references to the object remains. This helps avoiding memory leaks and is easy to use to implement RAII.
The subject is covered in depth in book "C++ Templates: The Complete Guide" by David Vandevoorde, Nicolai M. Josuttis, chapter Chapter 20. Smart Pointers.
Some topics covered:
Protecting Against Exceptions
Holders, (note, std::auto_ptr is implementation of such type of smart pointer)
Resource Acquisition Is Initialization (This is frequently used for exception-safe resource management in C++)
Holder Limitations
Reference Counting
Concurrent Counter Access
Destruction and Deallocation
Definitions provided by Chris, Sergdev and Llyod are correct. I prefer a simpler definition though, just to keep my life simple:
A smart pointer is simply a class that overloads the -> and * operators. Which means that your object semantically looks like a pointer but you can make it do way cooler things, including reference counting, automatic destruction etc.
shared_ptr and auto_ptr are sufficient in most cases, but come along with their own set of small idiosyncrasies.
A smart pointer is like a regular (typed) pointer, like "char*", except when the pointer itself goes out of scope then what it points to is deleted as well. You can use it like you would a regular pointer, by using "->", but not if you need an actual pointer to the data. For that, you can use "&*ptr".
It is useful for:
Objects that must be allocated with new, but that you'd like to have the same lifetime as something on that stack. If the object is assigned to a smart pointer, then they will be deleted when the program exits that function/block.
Data members of classes, so that when the object is deleted all the owned data is deleted as well, without any special code in the destructor (you will need to be sure the destructor is virtual, which is almost always a good thing to do).
You may not want to use a smart pointer when:
... the pointer shouldn't actually own the data... i.e., when you are just using the data, but you want it to survive the function where you are referencing it.
... the smart pointer isn't itself going to be destroyed at some point. You don't want it to sit in memory that never gets destroyed (such as in an object that is dynamically allocated but won't be explicitly deleted).
... two smart pointers might point to the same data. (There are, however, even smarter pointers that will handle that... that is called reference counting.)
See also:
garbage collection.
This stack overflow question regarding data ownership
A smart pointer is an object that acts like a pointer, but additionally provides control on construction, destruction, copying, moving and dereferencing.
One can implement one's own smart pointer, but many libraries also provide smart pointer implementations each with different advantages and drawbacks.
For example, Boost provides the following smart pointer implementations:
shared_ptr<T> is a pointer to T using a reference count to determine when the object is no longer needed.
scoped_ptr<T> is a pointer automatically deleted when it goes out of scope. No assignment is possible.
intrusive_ptr<T> is another reference counting pointer. It provides better performance than shared_ptr, but requires the type T to provide its own reference counting mechanism.
weak_ptr<T> is a weak pointer, working in conjunction with shared_ptr to avoid circular references.
shared_array<T> is like shared_ptr, but for arrays of T.
scoped_array<T> is like scoped_ptr, but for arrays of T.
These are just one linear descriptions of each and can be used as per need, for further detail and examples one can look at the documentation of Boost.
Additionally, the C++ standard library provides three smart pointers; std::unique_ptr for unique ownership, std::shared_ptr for shared ownership and std::weak_ptr. std::auto_ptr existed in C++03 but is now deprecated.
Most kinds of smart pointers handle disposing of the pointer-to object for you. It's very handy because you don't have to think about disposing of objects manually anymore.
The most commonly-used smart pointers are std::tr1::shared_ptr (or boost::shared_ptr), and, less commonly, std::auto_ptr. I recommend regular use of shared_ptr.
shared_ptr is very versatile and deals with a large variety of disposal scenarios, including cases where objects need to be "passed across DLL boundaries" (the common nightmare case if different libcs are used between your code and the DLLs).
Here is the Link for similar answers : http://sickprogrammersarea.blogspot.in/2014/03/technical-interview-questions-on-c_6.html
A smart pointer is an object that acts, looks and feels like a normal pointer but offers more functionality. In C++, smart pointers are implemented as template classes that encapsulate a pointer and override standard pointer operators. They have a number of advantages over regular pointers. They are guaranteed to be initialized as either null pointers or pointers to a heap object. Indirection through a null pointer is checked. No delete is ever necessary. Objects are automatically freed when the last pointer to them has gone away. One significant problem with these smart pointers is that unlike regular pointers, they don't respect inheritance. Smart pointers are unattractive for polymorphic code. Given below is an example for the implementation of smart pointers.
Example:
template <class X>
class smart_pointer
{
public:
smart_pointer(); // makes a null pointer
smart_pointer(const X& x) // makes pointer to copy of x
X& operator *( );
const X& operator*( ) const;
X* operator->() const;
smart_pointer(const smart_pointer <X> &);
const smart_pointer <X> & operator =(const smart_pointer<X>&);
~smart_pointer();
private:
//...
};
This class implement a smart pointer to an object of type X. The object itself is located on the heap. Here is how to use it:
smart_pointer <employee> p= employee("Harris",1333);
Like other overloaded operators, p will behave like a regular pointer,
cout<<*p;
p->raise_salary(0.5);
Let T be a class in this tutorial
Pointers in C++ can be divided into 3 types :
1) Raw pointers :
T a;
T * _ptr = &a;
They hold a memory address to a location in memory. Use with caution , as programs become complex hard to keep track.
Pointers with const data or address { Read backwards }
T a ;
const T * ptr1 = &a ;
T const * ptr1 = &a ;
Pointer to a data type T which is a const. Meaning you cannot change the data type using the pointer. ie *ptr1 = 19 ; will not work. But you can move the pointer. ie ptr1++ , ptr1-- ; etc will work.
Read backwards : pointer to type T which is const
T * const ptr2 ;
A const pointer to a data type T . Meaning you cannot move the pointer but you can change the value pointed to by the pointer. ie *ptr2 = 19 will work but ptr2++ ; ptr2-- etc will not work. Read backwards : const pointer to a type T
const T * const ptr3 ;
A const pointer to a const data type T . Meaning you cannot either move the pointer nor can you change the data type pointer to be the pointer. ie . ptr3-- ; ptr3++ ; *ptr3 = 19; will not work
3) Smart Pointers : { #include <memory> }
Shared Pointer:
T a ;
//shared_ptr<T> shptr(new T) ; not recommended but works
shared_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 functions
shptr->memFn();
(*shptr).memFn();
//
shptr.reset() ; // frees the object pointed to be the ptr
shptr = nullptr ; // frees the object
shptr = make_shared<T>() ; // frees the original object and points to new object
Implemented using reference counting to keep track of how many " things " point to the object pointed to by the pointer. When this count goes to 0 , the object is automatically deleted , ie objected is deleted when all the share_ptr pointing to the object goes out of scope.
This gets rid of the headache of having to delete objects which you have allocated using new.
Weak Pointer :
Helps deal with cyclic reference which arises when using Shared Pointer
If you have two objects pointed to by two shared pointers and there is an internal shared pointer pointing to each others shared pointer then there will be a cyclic reference and the object will not be deleted when shared pointers go out of scope. To solve this , change the internal member from a shared_ptr to weak_ptr. Note : To access the element pointed to by a weak pointer use lock() , this returns a weak_ptr.
T a ;
shared_ptr<T> shr = make_shared<T>() ;
weak_ptr<T> wk = shr ; // initialize a weak_ptr from a shared_ptr
wk.lock()->memFn() ; // use lock to get a shared_ptr
// ^^^ Can lead to exception if the shared ptr has gone out of scope
if(!wk.expired()) wk.lock()->memFn() ;
// Check if shared ptr has gone out of scope before access
See : When is std::weak_ptr useful?
Unique Pointer :
Light weight smart pointer with exclusive ownership. Use when pointer points to unique objects without sharing the objects between the pointers.
unique_ptr<T> uptr(new T);
uptr->memFn();
//T * ptr = uptr.release(); // uptr becomes null and object is pointed to by ptr
uptr.reset() ; // deletes the object pointed to by uptr
To change the object pointed to by the unique ptr , use move semantics
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
References :
They can essentially be though of as const pointers, ie a pointer which is const and cannot be moved with better syntax.
See : What are the differences between a pointer variable and a reference variable in C++?
r-value reference : reference to a temporary object
l-value reference : reference to an object whose address can be obtained
const reference : reference to a data type which is const and cannot be modified
Reference :
https://www.youtube.com/channel/UCEOGtxYTB6vo6MQ-WQ9W_nQ
Thanks to Andre for pointing out this question.
http://en.wikipedia.org/wiki/Smart_pointer
In computer science, a smart pointer
is an abstract data type that
simulates a pointer while providing
additional features, such as automatic
garbage collection or bounds checking.
These additional features are intended
to reduce bugs caused by the misuse of
pointers while retaining efficiency.
Smart pointers typically keep track of
the objects that point to them for the
purpose of memory management. The
misuse of pointers is a major source
of bugs: the constant allocation,
deallocation and referencing that must
be performed by a program written
using pointers makes it very likely
that some memory leaks will occur.
Smart pointers try to prevent memory
leaks by making the resource
deallocation automatic: when the
pointer to an object (or the last in a
series of pointers) is destroyed, for
example because it goes out of scope,
the pointed object is destroyed too.
A smart pointer is a class, a wrapper of a normal pointer. Unlike normal pointers, smart point’s life circle is based on a reference count (how many time the smart pointer object is assigned). So whenever a smart pointer is assigned to another one, the internal reference count plus plus. And whenever the object goes out of scope, the reference count minus minus.
Automatic pointer, though looks similar, is totally different from smart pointer. It is a convenient class that deallocates the resource whenever an automatic pointer object goes out of variable scope. To some extent, it makes a pointer (to dynamically allocated memory) works similar to a stack variable (statically allocated in compiling time).
What is a smart pointer.
Long version, In principle:
https://web.stanford.edu/class/archive/cs/cs106l/cs106l.1192/lectures/lecture15/15_RAII.pdf
A modern C++ idiom:
RAII: Resource Acquisition Is Initialization.
● When you initialize an object, it should already have
acquired any resources it needs (in the constructor).
● When an object goes out of scope, it should release every
resource it is using (using the destructor).
key point:
● 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.
Raw Pointers violate RAII: It need user to delete manually when the pointers go out of scope.
RAII solution is:
Have a smart pointer class:
● Allocates the memory when initialized
● Frees the memory when destructor is called
● Allows access to underlying pointer
For smart pointer need copy and share, use 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.
for smart pointer not own the raw pointer, use weak_ptr:
● not change Reference counting.
shared_ptr usage:
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 pointer
shared_ptr<T> t1 = shared_ptr<T>(pt);
shared_ptr<T> t2 = shared_ptr<T>(pt);
Always avoid using raw pointer.
For scenario that have to use raw pointer:
https://stackoverflow.com/a/19432062/2482283
For raw pointer that not nullptr, use reference instead.
not use T*
use T&
For optional reference which maybe nullptr, use raw pointer, and which means:
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.
Smart Pointers are those where you don't have to worry about Memory De-Allocation, Resource Sharing and Transfer.
You can very well use these pointer in the similar way as any allocation works in Java. In java Garbage Collector does the trick, while in Smart Pointers, the trick is done by Destructors.
The existing answers are good but don't cover what to do when a smart pointer is not the (complete) answer to the problem you are trying to solve.
Among other things (explained well in other answers) using a smart pointer is a possible solution to How do we use a abstract class as a function return type? which has been marked as a duplicate of this question. However, the first question to ask if tempted to specify an abstract (or in fact, any) base class as a return type in C++ is "what do you really mean?". There is a good discussion (with further references) of idiomatic object oriented programming in C++ (and how this is different to other languages) in the documentation of the boost pointer container library. In summary, in C++ you have to think about ownership. Which smart pointers help you with, but are not the only solution, or always a complete solution (they don't give you polymorphic copy) and are not always a solution you want to expose in your interface (and a function return sounds an awful lot like an interface). It might be sufficient to return a reference, for example. But in all of these cases (smart pointer, pointer container or simply returning a reference) you have changed the return from a value to some form of reference. If you really needed copy you may need to add more boilerplate "idiom" or move beyond idiomatic (or otherwise) OOP in C++ to more generic polymorphism using libraries like Adobe Poly or Boost.TypeErasure.

Why can't a weak_ptr be constructed from a unique_ptr?

If I understand correctly, a weak_ptr doesn't increment the reference count of the managed object, therefore it doesn't represent ownership. It simply lets you access an object, the lifetime of which is managed by someone else.
So I don't really see why a weak_ptr can't be constructed from a unique_ptr, but only a shared_ptr.
Can someone briefly explain this?
If you think about it, a weak_ptr must refer to something other than the object itself. That's because the object can cease to exist (when there are no more strong pointers to it) and the weak_ptr still has to refer to something that contains the information that the object no longer exists.
With a shared_ptr, that something is the thing that contains the reference count. But with a unique_ptr, there is no reference count, so there is no thing that contains the reference count, thus nothing to continue to exist when the object is gone. So there's nothing for a weak_ptr to refer to.
There would also be no sane way to use such a weak_ptr. To use it, you'd have to have some way to guarantee that the object wasn't destroyed while you were using it. That's easy with a shared_ptr -- that's what a shared_ptr does. But how do you do that with a unique_ptr? You obviously can't have two of them, and something else must already own the object or it would have been destroyed since your pointer is weak.
std::weak_ptr can't be used unless you convert it to std::shared_ptr by the means of lock(). if the standard allowed what you suggest, that means that you need to convert std::weak_ptr to unique in order to use it, violating the uniqueness (or re-inventing std::shared_ptr)
In order to illustrate, look at the two pieces of code:
std::shared_ptr<int> shared = std::make_shared<int>(10);
std::weak_ptr<int> weak(shared);
{
*(weak.lock()) = 20; //OK, the temporary shared_ptr will be destroyed but the pointee-integer still has shared to keep it alive
}
Now with your suggestion:
std::unique_ptr<int> unique = std::make_unique<int>(10);
std::weak_ptr<int> weak(unique);
{
*(weak.lock()) = 20; //not OK. the temporary unique_ptr will be destroyed but unique still points at it!
}
That has been said, you may suggest that there is only one unique_ptr, and you still can dereference weak_ptr (without creating another unique_ptr) then there is no problem. But then what is the difference between unique_ptr and shared_ptr with one reference? or moreover, what is the difference between a regular unique_ptr and C-pointers an get by using get?
weak_ptr is not for "general nonowning resources", it has a very specific job - The main goal of weak_ptr is to prevent circular pointing of shared_ptr which will make a memory leak. Anything else needs to be done with plain unique_ptr and shared_ptr.
A shared_ptr basically has two parts:
the pointed-to object
the reference count object
Once the reference count drops to zero the object (#1) is deleted.
The weak_ptr needs to be able to know if the object (#1) still exists. In order to do this, it has to be able to see the reference count object (#2), if it's not zero it can create a shared_ptr for the object (by incrementing the reference count). If the count is zero it will return an empty shared_ptr.
Consider the question of when can the reference count object (#2) be deleted? We must wait until no shared_ptr OR weak_ptr object refer to it. For this purpose the reference count object holds two reference counts, a strong ref and a weak ref. The reference count object will only be deleted when both these counts are zero. This means that part of the memory can only be freed after all the weak references are gone (this implies a hidden disadvantage with make_shared).
tl;dr; weak_ptr depends on a weak reference count which is part of shared_ptr, there cannot be a weak_ptr without a shared_ptr.
Conceptually, there is nothing preventing an implementation where a weak_ptr only provides access and a unique_ptr controls the lifetime. However, there are problems with that:
unique_ptr doesn't use reference counting to begin with. Adding the management structure for managing the weak references would be possible, but require an additional dynamic allocation. Since unique_ptr is supposed to avoid any(!) runtime overhead over a raw pointer, that overhead is not acceptable.
In order to use the object referenced by a weak_ptr, you need to extract a "real" reference from it, which will first validate that the pointer is not expired first and then give you this real reference (a shared_ptr in this case). This means that you suddenly have a second reference to an object that is supposed to be uniquely owned, which is a recipe for errors. This can't be fixed by returning a mixed half-strong pointer that only temporarily delays possible destruction of the pointee, because you could just as well store that one, too, defeating the idea behind unique_ptr.
Just wondering, what problem are you trying to solve using a weak_ptr here?
Looks like everyone is writing here about std::weak_ptr but not about weak poiner concept which I believe is what the author is asking for
I think that no one mentioned why standard library is not providing weak_ptr for unique_ptr. Weak pointer CONCEPT doesn't disclaims unique_ptr usage. Weak pointer is only an information if the object has been already deleted so it's not a magic but very simple generalized observer pattern.
It's because of threadsafety and consistency with shared_ptr.
You just simply can't guarantee that your weak_ptr (created from unique_ptr existing on other thread) will be not destroyed during calling method on pointed object.
It's because weak_ptr needs to be consistent with std::shared_ptr which guarantee threadsafety. You can implement weak_ptr which works correctly with unique_ptr but only on the same thread - lock method will be unnecessary in this case. You can check chromium sources for base::WeakPtr and base::WeakPtrFactory - you can use it freely with unique_ptr.
Chromium weak pointer code is most probably based on last member destruction - you need to add factory as a last member and after that I believe that WeakPtr is informed abut object deleteion (I'm not 100% sure) - so it doesn't looks so hard to implement.
Overall using unique_ptr with weak pointer concept is OK IMHO.
No-one has mentioned the performance aspect of the problem yet, so let me throw my $0.02 in.
weak_ptr must somehow know when the corresponding shared_ptrs have all gone out of scope and the pointed object has been deallocated and destroyed. This means that shared_ptrs need to communicate the destruction towards each weak_ptr to the same object somehow. This has a certain cost – for example, a global hash table needs to be updated, where weak_ptr gets the address from (or nullptr if the object is destroyed).
This also involves locking in a multi-threaded environment, so it can potentially be too slow for some tasks.
However, the goal of unique_ptr is to provide a zero-cost RAII-style abstraction class. Hence, it should not incur any other cost than that of deleteing (or delete[]ing) the dynamically allocated object. The delay imposed by doing a locked or otherwise guarded hash table access, for example, may be comparable to the cost of deallocation, however, which is not desirable in the case of unique_ptr.
It may be useful to distinguish reasons for preferring a unique_ptr over a shared_ptr.
Performance One obvious reason is computational-time and memory use. As currently defined, shared_ptr objects typically need something like a reference-count value, which takes space and also must be actively maintained. unique_ptr objects don't.
Semantics With a unique_ptr, you as the programmer have a pretty good idea when the pointed-to object is going to be destroyed: when the unique_ptr is destroyed or when one of its modifying methods is called. And so on large or unfamiliar code bases, using unique_ptr statically conveys (and enforces) some information about the program's runtime behavior that might not be obvious.
The comments above have generally focused on the performance-based reasons that it would be undesirable for weak_ptr objects to be tied to unique_ptr objects. But one might wonder if the semantics-based argument is sufficient reason for some future version of the STL to support the use-case implied by the original question.
After many years of c++ programing works, i finally realized that the correct way in c++ world is not to use shared_ptr/weak_ptr for ever. We have spent so many time to fix the bugs caused by the unclear ownership of share_ptr.
The solution is to use unque_ptr and some weak pointer for unique_ptr instead, just as what's expected in this topic.
cpp standard library has no weak pointer for unique_ptr, so i create a very simple, but useful libary here --
https://github.com/xhawk18/noshared_ptr
It has two new smart pointers,
noshared_ptr<T>, a new kind of unique_ptr
noweak_ptr<T>, the weak pointer for noshare_ptr<T>
I demonstrated the problem to myself with a MWE implementing weak_ptr on single objects. (I implement it on X here, but X can be anything that can tell us when it dies, such as a unique_ptr with a custom deleter).
The ultimate problem however is that at some point we need reference counting on the weak pointers themselves, because while X is not shared, the weak pointers are shared. This takes us full circle back to using shared_ptr again.
Perhaps the only advantage of doing this is that the intent of single ownership is clearer and cannot be violated, however, as Stroustrup suggests and is quoted this answer, this can be hinted at with the using statement.
#include <iostream>
#include <memory>
template<typename T>
struct ControlBlock
{
T* Target;
explicit ControlBlock(T* target) : Target(target) {}
};
template<typename T>
struct WeakReference
{
std::shared_ptr<ControlBlock<T>> ControlBlock;
T* Get() { return ControlBlock ? ControlBlock->Target : nullptr; }
};
template<typename T>
struct WeakReferenceRoot
{
WeakReference<T> _weakRef;
WeakReferenceRoot(T* target) : _weakRef{std::make_shared<ControlBlock<T>>(target)} { }
const WeakReference<T>& GetReference() { return _weakRef; }
~WeakReferenceRoot() { _weakRef.ControlBlock->Target = nullptr; }
};
struct Customer
{
WeakReferenceRoot<Customer> Weak{this};
};
int main() {
WeakReference<Customer> someRef;
std::cout << "BEFORE SCOPE - WEAK REFERENCE IS " << someRef.Get() << "\n";
{
Customer obj{};
someRef = obj.Weak.GetReference();
std::cout << "IN SCOPE - WEAK REFERENCE IS " << someRef.Get() << "\n";
}
std::cout << "OUT OF SCOPE - WEAK REFERENCE IS " << someRef.Get() << "\n";
return 0;
}
Sadly as with many cases - cause the C++ committee just didn't care and dismissed such usecases.
How it is:
weak_ptr was specified in terms of shared-pointer, precluding any attempts at making it a more broadly useful smart-pointer. In C++ conceptually a weak-ptr is a non-owning pointer that MUST be converted to a shared_ptr to access the underlying object. And as a unique_ptr does not support any sort of reference-counting (as it is the unique owner by definition) converting a weak_ptr to a pointer with any sort of ownership is not allowed.
It is sadly a bit too late to get good well-named smart-pointers that offer a bit more generality.
But you can create something like that:
To make it safe you would need your own deleter (unique_ptr has the deleter in the type), and a new non-owning unique_ptr_observer that changes the deleter. When creating an observer it would register a cleanup-handler as the deleter. That way you can have a unique_ptr_observer that can check if the Threadsafety would still be a problem as you would need either a locking-mechanism, create copies for readout, or some other way to prevent the pointer from getting deleted while you are actively looking at it.
(it is so annoying that the deleter is part of the type.......)

Some questions about shared_ptr, scoped_ptr and shared_array

I have some questions about smart pointers implemented in boost library.
Is the only diffrence between shared_ptr and scoped_ptr that scoped_ptr doesn't have copy constructor and shared_ptr has it?
Should i use then scoped_ptr instead of shared_ptr always when object doesn't call copy constructor?
I also doesn't understand idea of shared/scoped array. Can't I just use std::vector instead of it?
Is the only diffrence between shared_ptr and scoped_ptr that
scoped_ptr doesn't have copy constructor and shared_ptr has it?
The difference is more fundamental than that; it has to do with how the smart pointers own the object it points to. What makes smart pointers different from dumb pointers is that the concept of ownership is a core component of their function. The ownership semantics is what differentiates the different kinds of smart pointers.
Because smart pointers "own" the thing they point to, they can do useful things like deleting objects when the smart pointers go away (this is made possible using only the rules of the language; no compiler magic is needed). This way, memory management can be made almost automatic in C++ (despite claims to the contrary, there's very little manual memory management required in modern C++).
shared_ptr implements reference-counting
semantics for
memory management. Multiple shared_ptrs can own a single object. A
shared_ptr going away does not necessarily delete the object it
points to because there may be another shared_ptr owning the
object. The last shared_ptr that owns an object and goes away will
delete the object it owns.
scoped_ptr implements exclusive-ownership semantics. Only one
scoped_ptr can own any one object. When a scoped_ptr goes away,
it will always delete the object it owns (because there's only one
owner). It's typically used as a lightweight RAII mechanism for
objects allocated on the free store.
The array versions (shared_array and scoped_array) have essentially the same semantics, but are designed specifically for arrays e.g. they use delete[] instead of delete, implements the array subscript operator, etc.
shared_ptr and shared_array also allows you to specify a custom deleter, if the default delete behavior is not appropriate for the object. scoped_ptr and scoped_array do not have that ability, since they are quite lightweight compared to shared_ptr and shared_array.
In C++11, the newest and current version of C++, there's also a unique_ptr, which is just like scoped_ptr except that you can transfer the ownership of an object to another unique_ptr. In C++03, an older but more widely supported version of C++, there's auto_ptr which is equivalent to unique_ptr except it was easy to use it in an unsafe manner by accident (which is why it is deprecated in C++11).
Should i use then scoped_ptr instead of shared_ptr always when object
doesn't call copy constructor?
Which one you choose doesn't depend on the presence of the copy-constructor, since shared_ptr and scoped_ptr does not require the object to be copy-constructible. You pick the one depending on the required ownership semantics. If the object will have multiple owners, you use shared_ptr. If the object will only have one owner and the object's existence lasts only within a scope, use scoped_ptr (hence the name scoped_ptr).
I also doesn't understand idea of shared/scoped array. Can't I just
use std::vector instead of it?
std::vector does not implement reference-counting semantics like shared_array does. std::vector is more like scoped_array, but can be copied. When you copy a std::vector, you also copy all of the elements it contains. That's not the case for scoped_array. std::vector also has functions that allow you to manipulate and examine its contents (e.g. push_back, insert, erase, etc.), but is much more heavyweight than scoped_array.
Yes. scoped_ptr does not allow for copies while shared_ptr does. But this "simple" difference makes a world of impact on both the implementation and the usage of the smart pointer.
scoped_ptr is faster and lighter than shared_ptr because no reference counting is involved. shared_ptr will count the number of assignments and not delete the object until all references have expired/gone out of scope.
Now your question regarding vectors implies that you're actually not familiar with the the concept of dynamic allocation and the difference between that and static allocation on the static. You really should look into reading a primer on C(++) and look into the reasons for dynamic allocation and when you need it.
A vector stores a list of objects. A XXX_ptr stores a pointer to a (single) dynamically-allocated object. Apples and oranges.
If you allocate memory, you can put the newly created pointer in a scoped pointer, so that IF the malloc/noew fails, the memory will be freed. This is how I usally uses it, or if it's an object that needs to be allocated on the heap, but that I want to treat it as a stack object in terms of that it will only be alive until the end of the scope.
The shared pointer is if you want to pass the pointer around and allow the object to have multiple owners. Then none of the owners needs to take responibility of the object and they can all just stop using it and be sure that it will be freed correclty. (you don't wanna free an object that you know is used by someone else)
I'd say you're thinking about it the wrong way. The question isn't whether you do call the copy constructor -- it's whether you need to call the copy constructor. In other words, you should be deciding whether to use shared_ptr or scoped_ptr not based on reading your code but based on thinking about object ownership and what objects' lifetimes should be.
Say you have an object that you want to create on the heap, not on the stack, for whatever reason (maybe it's too big to be on the stack, maybe you might want to replace it with a different object at some point, maybe you want it to be initialized late) but its lifetime should never be longer than its containing scope. A common example of this is instance variables in a class: they should often be deleted when the object they are in is deleted. Then, you should use scoped_ptr.
But sometimes you don't know when an object will be safe to delete in advance. For instance, consider an object in a lookup table. You want to return it in response to lookups, but what happens when it's deleted -- could someone still be using the object who looked it up previously? In cases like this, you can use shared_ptr, which shares the objects ownership so that it only gets deleted when nobody has a copy of the pointer anymore.
So why does anyone ever use scoped_ptr instead of shared_ptr? First of all, knowing when the destructor gets called is one of the big advantages of non-memory-managed languages like C++. Maybe the destructor is expensive, or maybe it frees a resource; it's nice to know when these things happen. Also, with shared_ptr, there's the potential for memory leaks if you create a circular reference by accident.
In general, almost every pointer you have should be "owned" -- there should be a single place in your code that news and deletes it. scoped_ptr is great for this; when you want an owned object to be passed around to non-owners you can use a bare pointer. But if you absolutely need an object's ownership to be shared, use shared_ptr -- as long as you're careful to use it correctly!
As for scoped/shared arrays, you can certainly use std::vector, but arrays are cheaper and sometimes people want the performance benefit.
shared_ptr is very different from scoped_ptr. scoped_ptr (which is now standardized in C++11 as std::unique_ptr) is simply a RAII-style smart pointer which takes ownership of a resource and then deallocates the owned resource when the pointer goes out of scope.
A shared_ptr however, may share ownership of the resource with other instances of shared_ptr. The resource stays alive as long as one or more shared_ptr instances own it. This is an automatic memory-management technique, (a form of garbage-collection) known as reference counting. It basically provides the same effect as more advanced garbage collection algorithms, except unlike other garbage collection techniques, it doesn't handle circular references.
As for using std::vector versus boost::scoped_array, yeah - scoped_array doesn't really offer much of an advantage. However, boost::shared_array offers reference counting semantics, just like shared_ptr.

Will the smart pointer or scoped pointers delete an object when the class has no destructor

Will the smart pointer or scoped pointers delete an object when the class has no destructor
If not, why not just leave the scope and let the object be deleted by itself?
All class members are deleted even if you don't have a destructor when the instance is deleted. Memory leaks occur when you deal with pointers:
class A
{
private:
B* b;
};
In this case, b itself will be destroyed when the instance of A is deleted, but the memory it points to will not.
class A
{
private:
SmartPtr<B> b;
};
In the case of smart pointers, which usually have some reference counting and memory cleanup in the destructor, the memory it points to will be explicitly destroyed by its destructor, and the destructor of the smart pointer will be implicitly called when the instance of the containing class is destroyed.
yes. that s what smart pointers are used for.
http://www.boost.org/doc/libs/1_48_0/libs/smart_ptr/smart_ptr.htm
http://en.wikipedia.org/wiki/Smart_pointer
What is a smart pointer and when should I use one?
Yes, smart pointer deletes the object irrespective of whether class has destructor or not. Note that smart pointers are used with objects allocated on heap (using new) and these object won't release memory when they go out of scope, you need to explicitly delete them. Smart pointers will remove this process of explicitly deleting them.
The pointer to the object itself will be deleted. However if there is any dynamically allocated data in the class it will not get freed. The idea of having a destructor is to be able to post-process the class object and mainly - free any resources taken.
new and delete do two things.
new allocates memory and gets an object to construct itself in that memory space.
delete first gets the object to destruct itself then releases the memory.
Note that some smart pointers can be given a custom deleter which doesn't call delete on the object but whatever you ask it to do. There may be occasions when you wish to pass it a no-op.
Your point is well taken; there aren't that many uses for smart pointers
in C++, since most of the time where they might be relevant, you'd be
better off using value semantics, and copying. In the case of
scoped_ptr, the most frequent use is when the actual object is
polymorphic:
scoped_ptr<Base> pObj = condition
? static_cast<Base*>( new Derived1 )
: static_cast<Base*>( new Derived2 );
(Regretfully, at least one of the static_cast is necessary.)
If you are dealing with a container of polymorphic objects, you'll need
shared_ptr instead, and if you're returning a polymorphic object, or
otherwise passing it around, you will use unique_ptr if you can
guarantee its availability, and auto_ptr otherwise—in some cases
where you're passing it around, shared_ptr might be more appropriate.
In the case of returning an object or passing it around, the cost of
copying it might also be a motive for using a smart pointer, even if the
object isn't polymorphic. In such cases, I'd still use value semantics
(i.e. copying and assigning the object itself) unless I had a
performance problem.
Note that smart pointers aren't only used for memory management. I
regularly use auto_ptr in the interface of queues between threads:
once the object has been inserted into the queue, it no longer belongs
to the sending thread; auto_ptr expresses these semantics exactly,
with the auto_ptr in the sending thread becoming invalid. Or a
modifiable singleton (something which should be very, very rare) might
acquire a lock in its instance function, and return a shared_ptr
which frees the lock in its final destructor. I've also used smart
pointers in one or two cases to ensure transactional semantics: in one
case, for example, the objects were in a number of different sets (which
held pointers to them, of course), ordered according to different
criteria. To modify an object, you acquired a shared pointer to it; the
function which returned this shared pointer also removed the objects
from the sets, so that you could safely modify the key values as well,
and the final destructor reinserted them into the sets according to the
new keys. And so on—there are any number of uses for smart
pointers that have nothing to do with memory management or object
lifetime.