Vector of SharedPointers without C++11 move

Hey,

As far as i know if I want to store a smart pointer(lets take shared pointer) i have to use std::move(..) , otherwise the vector will contain a copy of the smart pointer. But is there any other way to prevent the shared pointer form getting copied on the vector?

I have to use a older C++ version, but ,my framework provides smartpointers.

can anyone help?
The only reason to use shared_ptr is when you intend to make copies of the pointer (and those copies share ownership).

If you need a vector of uniquely-owned heap-allocated objects and vector<unique_ptr> is not available, boost has a library for that: http://www.boost.org/doc/libs/release/libs/ptr_container/doc/ptr_container.html

to quote their intro,
Whenever a programmer wants to have a container of pointers to heap-allocated objects, there is usually only one exception-safe way: to make a container of smart pointers like boost::shared_ptr This approach is suboptimal if

* the stored objects are not shared, but owned exclusively, or
* the overhead implied by smart pointers is inappropriate

This library therefore provides standard-like containers that are for storing heap-allocated or cloned objects
Last edited on
yeah, and i also want to make copies form the pointer.

i've rarely used smartpointers

1
2
3
4
5
6
7
8
  
std::vector<std::shared_ptr<Object>         vec;

somewhereelse()
{
  std::shared_ptr<Object> objptr( new Object() );
  vec.push_back( objptr );
}

here objptr(tmp variable) is copied into my vector, does this cause any problems(reference counting, leak, ..), or is everything cleared&destructed after my vector goes out of scope.

-----

Update:
(didn't read the quote)
But with std:move(..) it's exception safe to store share_ptrs inside a vector?
Last edited on
my framework provides smartpointers.

There are plenty of different "smart pointers". C++ standard library has now many, Boost have similar, your framework has something. You have to know the features of the types that are at your disposal.


When a std::vector object is destructed, all of its elements are destructed.
The elements in your example are std::shared_ptr objects.
When a std::shared_ptr object is destructed and it is the last copy holding the address in it, it will deallocate and destruct the object at the address.

In your example the line 7 creates a copy. The scope of objptr ends at line 8, so the objptr is destructed, but the copy in vec lives on, as does the dynamically allocated Object. When vec goes out of scope, so does the copy created from objptr, and unless you have made additional copies, the Object as well. Properly.


Note though that the following does not have copies:
1
2
3
4
5
{
  Object * obj = new Object;
  std::shared_ptr<Object> foo( obj );
  std::shared_ptr<Object> bar( obj );
} // error: double deletion; foo is not a copy of bar 
oh wait, so a container of shared_ptr is ok? and a container of unique pointers is not?

the overhead implied by smart pointers is inappropriate

Do they mean the reference count overhead, compared to unique_ptr or raw pointers?
Last edited on
Read the ptr_container documentation at the Boost site. (Follow that link in Cubbi's post.)

To some even the overhead of dereferencing raw pointers is too much and thus they avoid runtime polymorphism. Every smart pointer type has something extra compared to raw pointers. You have to know what each does, how it does it, what benefits that gives, and where it does not fit. There are published analysis about some smart pointers.

boost::ptr_containers are smart pointers too. Even std::vector and std::string are sugar-coated pointers.
unfortunatly boost is no option for me (maybe the framework provides something similar).

As far as I know there are some cases where smart pointers should be chose over raw pointers, and other cases where raw pointers should be chose over smart pointers.

But right now i'm just curious whats the best way to do it with the C++ STL, without any other framework/library.


Different Question about smart pointers and performance:

I want to have a vector of object(big objects):
std::vector<MyObject> vec;

whats the performance compared to a vector of smart pointers?
std::vector<std::shared_ptr<MyObject>> vec;

Somewhere I read, if there are lots of updates on the object/vector(not quite sure anymore) the vector of smart pointers would have better performance.
(maybe the framework provides something similar)

If you have to use specific tools (language and framework) then you should make your business to know them inside and out.

do it with the C++ STL

With C++14, which you cannot use, or with older C++ that does not have smart pointers in STL?


The reference documentation for std::vector does describe the computational complexity of vector operations. Before the move, stored objects had to be copyable. Thus copy construction and copy assignment are particularly interesting.
Whats the difference between new and make_shared of a smart pointer?
Does using new cause any problem/leak in combination with my example from above:

1
2
std::shared_ptr<Object> objptr( new Object() );
  vec.push_back( objptr );


Found this somewhere:

The main difference is that the first requires two memory allocations: one for the managed object (new int), and one for the reference count. make_shared should allocate a single block of memory, and create both in that.
Last edited on
http://stackoverflow.com/questions/20895648/difference-in-make-shared-and-normal-shared-ptr-in-c

Scott Meyers explains a lot in his
"Effective Modern C++: 42 Specific Ways to Improve Your Use of C++11 and C++14." (2014)
Moreover, code such as f(std::shared_ptr<int>(new int(42)), g()) can cause a memory leak if g throws an exception because g() may be called after new int(42) and before the constructor of shared_ptr<int>.

This doesn't occur in f(std::make_shared<int>(42), g()), since two function calls are never interleaved.

http://en.cppreference.com/w/cpp/memory/shared_ptr/make_shared
"Effective Modern C++: 42 Specific Ways to Improve Your Use of C++11 and C++14." (2014)

this book is already on my list. But currently i'm reading a other book.

so my example should be fine right?
Last edited on
> so my example should be fine right?

Yes.

vec.push_back( std::shared_ptr<Object>( new Object ) ) ; would also be fine.
Exception safety: If an exception is thrown, delete p is called.


If new must be used, favour: vec.emplace_back( new Object ) ;

This is canonical: vec.push_back( std::make_shared<Object>() ) ;
Topic archived. No new replies allowed.