views:

55

answers:

3

I have this situation where the library I use has many functions that return raw pointers to objects, how could I now use boost smart pointers in my program using this library and using smart pointers?

The library is xerces-C++ and an example is getting the document iterator:

boost::shared_ptr<DOMNodeIterator> itera = document->createNodeIterator(rootelement, DOMNodeFilter::SHOW_ALL, NULL, true);

The createNodeIterator function returns a pointer to a DOMNodeIterator object, this is a raw pointer and therefore cannot be cast just like that to a boost::shared_ptr... How would I best deal with this? Use raw pointers instead?

+5  A: 

I guess the library provides a way of releasing those raw pointers ?

If so, you can just "create" a shared_ptr with a custom deleter, specifying the "free function" provided by the library.

Example:

If you have the two functions:

Foo* createFoo();
void freeFoo(Foo* foo);

You can create a shared_ptr that way:

boost::shared_ptr<Foo> foo(createFoo(), freeFoo);

If the raw pointer is not meant to be released, you can instead provide a "null-deleter" that does nothing when the reference counter reaches 0.

ereOn
the library provides a release method to release the pointers....
Tony
@Tony: Can you give me the code that releases a raw pointer ? I could then show you an example solution.
ereOn
@ereOn: You saying you want the implementation of the DOMNodeIterator::release function?
Tony
@Tony: Dunno. Just a sample code on how you allocate then release such a raw pointer. I never used Xerces.
ereOn
in most cases you allocate with new and the object has a release() function...
Tony
@ereOn why will you need a smart pointer if no cleanup is necessary?
ruslik
@ruslik: For consistency's sake. Sometimes, you design an API which returns smart pointers. Depending on several things, you might either want to return a "owned" smart pointer or a "null deleter" one. The caller of your API don't have to care about deallocation and uses the same type everywhere.
ereOn
A: 

You can change boost::shared_ptr<DOMNodeIterator> itera = document->createNodeIterator(rootelement, DOMNodeFilter::SHOW_ALL, NULL, true); to boost::shared_ptr<DOMNodeIterator> itera( document->createNodeIterator(rootelement, DOMNodeFilter::SHOW_ALL, NULL, true)); and it should compile fine.

Naveen
And what if the library does not use `new` to allocate the pointer ? The `shared_ptr` will then use `delete` when something else was expected, leading to undefined behavior.
ereOn
Yes, you are right. I assumed that since OP wanted to use a `shared_ptr` the intention is to automatically `delete` the object.
Naveen
@ereOn, @Naveen: That concrete library requires user code to call a custom function to release the memory.
David Rodríguez - dribeas
A: 

If you are creating the object locally use boost::scoped_ptr instead of boost:shared_ptr as this is very dangerous if you pass as a parameter to some other function. If you are dealing with shared_ptr, you have think about object reference count as well.

If you use Scoped_ptr, it automatically deletes when scope of the object ends.

Class Foo boost::scoped_ptr objfoo(new Foo());

Raghuram Reddy N
The problem (unspecified in the question) is that the concrete library requires the user to call a custom function to release the memory. That requirement does not fit well with using `scope_ptr`
David Rodríguez - dribeas