We have a C++ library that we provide to several different clients. Recently we made the switch from using raw pointers in the public interface to using boost::sharedptr instead
Use auto_ptr
or stick to a C interface. Forcing C++ libs into your interface is always ugly, kills any chance of being cross platform, and causes a maintenance nightmare for customers with different "downstream" configurations.
As soon as C++0x is mainstream enough for your clients, switch to std::shared_ptr
.
One possible solution is to ship boost::shared_ptr with your project. As it all consists of headers, this would free your clients from having to install the boost libraries manually. You can use bcp to get all files needed by a particular boost library, including the libraries itself. I did that when i worked for a company back then and needed boost::shared_ptr
and it actually worked greatly.
This is an interesting question I have had for some time. Do you force your users into whatever library you provide, or let them decide on what is best in their project? As always, the question is what you are offering and what you are requiring from the user.
If you use raw pointers, you allow all sorts of possibilities. The user code can use a raw pointer, store it into std::auto_ptr, shared_ptr (whether boost or TR1), or their homebrewed version of a smart pointer. But this may also get the user into trouble if they forget to release the memory, and it requires some more code in their side if they just want a temporary created for a method call (if you provide raw pointers, they will have to store the pointer in a non-temporary [possibly smart] pointer variable).
Now, if you use a smart pointer you are forcing your solution into the user. If they plan on using their own version of a smart pointer (say you use boost::shared_ptr and they want std::tr1::shared_ptr) they are no longer allowed to use it if they work with your interface. Whatever smart pointer you decide upon (besides std::auto_ptr that is special) you are not only forcing a solution, but also the problems it has.
If your user has a multithreaded application, and your solution is not thread safe, the user is bound to an unsafe solution. If on the other hand the smart pointer is thread safe but inccurs locking costs, those costs are pushed to your users even if they work in a multithreaded application. If you compile your library (not a header only lib) then you are forcing not only a type of smart pointer, but also a particular version of it, since any changes in the smart pointer library will break compatibility of your code.
As a side note, boost::shared_ptr (boost 1.33+) is thread safe in most situations, and it uses a lock-free implementation in many platforms. Anyway this should give you an idea of things you should consider.
Finally, you must consider that you are not only binding the user into using your type of smart pointer, but also the same version of it. If you compile your lib against a particular version of boost the user is bound to that particular implementation o
boost::intrusive_ptr perhaps?
shared_ptr<> is part of the language, as of the release of TR1. See: (TR1)
introducing boost::shared_ptr forces your client to use boost. to some people, this is a minor issue.
it also forces your clients to use the same compiler as used by your lib, if your lib is distributed as compiled binary. or, if your library is distributed in source code, the clients have to stick to their own choice of compiler used to compile your lib. this isn't a minor issue to any project of considerable size.