Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Example to use shared_ptr?

Hi I asked a question today about How to insert different types of objects in the same vector array and my code in that question was

 gate* G[1000]; G[0] = new ANDgate() ; G[1] = new ORgate; //gate is a class inherited by ANDgate and ORgate classes class gate {  .....  ......  virtual void Run()    {   //A virtual function    } }; class ANDgate :public gate    {.....    .......    void Run()    {     //AND version of Run    }    };  class ORgate :public gate    {.....    .......    void Run()    {     //OR version of Run    }    };       //Running the simulator using overloading concept  for(...;...;..)  {   G[i]->Run() ;  //will run perfectly the right Run for the right Gate type  }  

and I wanted to use vectors so someone wrote that I should do that :

std::vector<gate*> G; G.push_back(new ANDgate);  G.push_back(new ORgate); for(unsigned i=0;i<G.size();++i) {   G[i]->Run(); } 

but then he and many others suggested that I would better use Boost pointer containers
or shared_ptr. I have spent the last 3 hours reading about this topic, but the documentation seems pretty advanced to me . ****Can anyone give me a small code example of shared_ptr usage and why they suggested using shared_ptr. Also are there other types like ptr_vector, ptr_list and ptr_deque** **

Edit1: I have read a code example too that included:

typedef boost::shared_ptr<Foo> FooPtr; ....... int main() {   std::vector<FooPtr>         foo_vector; ........ FooPtr foo_ptr( new Foo( 2 ) );   foo_vector.push_back( foo_ptr ); ........... } 

And I don't understand the syntax!

like image 1000
Ahmed Avatar asked Aug 13 '10 12:08

Ahmed


People also ask

When should you use a shared_ptr?

An object referenced by the contained raw pointer will not be destroyed until reference count is greater than zero i.e. until all copies of shared_ptr have been deleted. So, we should use shared_ptr when we want to assign one raw pointer to multiple owners. // referring to the same managed object.

In what situation is a shared_ptr more appropriate than a unique_ptr?

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.

What does shared_ptr get () do?

A shared_ptr may share ownership of an object while storing a pointer to another object. get() returns the stored pointer, not the managed pointer.

What is shared_ptr?

The shared_ptr type is a smart pointer in the C++ standard library that is designed for scenarios in which more than one owner might have to manage the lifetime of the object in memory.


1 Answers

Using a vector of shared_ptr removes the possibility of leaking memory because you forgot to walk the vector and call delete on each element. Let's walk through a slightly modified version of the example line-by-line.

typedef boost::shared_ptr<gate> gate_ptr; 

Create an alias for the shared pointer type. This avoids the ugliness in the C++ language that results from typing std::vector<boost::shared_ptr<gate> > and forgetting the space between the closing greater-than signs.

    std::vector<gate_ptr> vec; 

Creates an empty vector of boost::shared_ptr<gate> objects.

    gate_ptr ptr(new ANDgate); 

Allocate a new ANDgate instance and store it into a shared_ptr. The reason for doing this separately is to prevent a problem that can occur if an operation throws. This isn't possible in this example. The Boost shared_ptr "Best Practices" explain why it is a best practice to allocate into a free-standing object instead of a temporary.

    vec.push_back(ptr); 

This creates a new shared pointer in the vector and copies ptr into it. The reference counting in the guts of shared_ptr ensures that the allocated object inside of ptr is safely transferred into the vector.

What is not explained is that the destructor for shared_ptr<gate> ensures that the allocated memory is deleted. This is where the memory leak is avoided. The destructor for std::vector<T> ensures that the destructor for T is called for every element stored in the vector. However, the destructor for a pointer (e.g., gate*) does not delete the memory that you had allocated. That is what you are trying to avoid by using shared_ptr or ptr_vector.

like image 78
D.Shawley Avatar answered Oct 24 '22 20:10

D.Shawley