From: Andrey Semashev (andrey.semashev_at_[hidden])
Date: 2008-05-12 10:20:30
I've seen this topic floating around but it seems it didn't make it into
boost for some reason. I propose to add a new helper function for
shared_ptr, namely new_shared. The function would dynamically allocate
an object and return shared_ptr that points to it. The function provides
the following benefits:
- It may perform better than allocating the object and constructing
shared_ptr explicitly. Obviously, it allows to get rid of the additional
allocation for the counter object.
- The function is effectively a safer replacement for the core operator
new. It solves the frequently missed memory leak pointed out by Meyers:
foo(shared_ptr< A >(new A), bar());
I've made a quick implementation that supports the following:
- Arbitrary number of constructor arguments. C++0x features (variadic
templates and rvalue references) are supported in addition to the
traditional and more limited C++03 version.
- Support for custom deleters, which are now more "destroyers" because a
deleter used with the new_shared function should not free memory from
the destroyed object.
- Support for custom allocators. It is through allocators the memory for
both the object and the counter are allocated and deallocated.
- The shared_ptr implementation is intact, the new feature is a pure
addition (however, it could be made a bit more effective with a little
help from shared_ptr).
The implementation is available in the Vault:
Some quick examples of use:
shared_ptr< A > p1 = new_shared< A >(); // default ctor
shared_ptr< B > p2 = new_shared< B >(x, y, z); // parametrized ctor
shared_ptr< C > p3 = new_shared< C >(ref(x)); // passing references
// using custom deleter
shared_ptr< D > p4 = new_shared< D >(use_deleter(d));
// using custom allocator
shared_ptr< E > p5 = new_shared< E >(use_allocator(a));
// you can mix the above cases
shared_ptr< F > p6 = new_shared< F >(
use_deleter(d), use_allocator(a), x, ref(y));
shared_ptr< G > p7 = new_shared< G >(
use_allocator(a), use_deleter(d), z);
The use_allocator and use_deleter arguments may be in either order, but
must be the first arguments of new_shared, if used.
Do you think this would be a reasonable addition to Boost.SmartPtr?
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk