I’m creating a c++ library that makes heavy use of smart pointers, both in public interface and internally. Currently it is “header-only”, but as it evolves it is becoming clear that this may not be appropriate.
I don’t want to dictate a choice of smart pointer implementation to library users. I also have gotten pretty far without bringing in any dependencies (such as boost), and would like to stay dependency-free as long as possible. The library isn’t targeting c++0x, and (unsurprisingly) wants to stay as standards-compliant as possible.
Currently, my solution for letting users select an implementation looks like this:
#ifndef MYLIB_MEMORY_H_
#define MYLIB_MEMORY_H_
#if MYLIB_STD_SMART_PTR
#include <memory>
#define MYLIB_SHARED_PTR std::shared_ptr
#define MYLIB_WEAK_PTR std::weak_ptr
#define MYLIB_STATIC_POINTER_CAST std::static_pointer_cast
#elif MYLIB_STD_TR1_SMART_PTR
#include <tr1/memory>
#define MYLIB_SHARED_PTR std::tr1::shared_ptr
#define MYLIB_WEAK_PTR std::tr1::weak_ptr
#define MYLIB_STATIC_POINTER_CAST std::tr1::static_pointer_cast
#elif MYLIB_BOOST_SMART_PTR
#include <boost/shared_ptr.hpp>
#define MYLIB_SHARED_PTR boost::shared_ptr
#define MYLIB_WEAK_PTR boost::weak_ptr
#define MYLIB_STATIC_POINTER_CAST boost::static_pointer_cast
#else
#error Please define one of MYLIB_STD_SMART_PTR, MYLIB_STD_TR1_SMART_PTR or MYLIB_BOOST_SMART_PTR
#endif
#endif // MYLIB_MEMORY_H_
Since the library is currently header-only, choosing a macro at (client) compile time is sufficient. I’m afraid that if I move to a shared library, this trick will break down and I’ll have to find another way.
What might that other way be?
Not an answer
I would take a different approach to the selection of the shared pointer, mainly because I dislike macros.
Now, relating to the actual question, if the smart pointers are used as part of the public interface of a compiled in library you will have to provide different binaries and have the user pick which binary to link against. Then again, I would try avoiding the use of
shared_ptrin the API of a library, as it forces your choice of smart pointer onto your users (unless, of course, your library does share the pointers with the clients), and rather usestd::auto_ptrthat has the advantage of being able to manage the memory automatically and at the same time allow the user to decide to move the resource to any other type of pointer by callingrelease()(once ashared_ptrobtains ownership of a resource, it cannot give ownership back).