My question revolves around whether or not I must expose my use of the boost::shared_ptr from my interface and whether or not I should expose raw pointers or references from my interface.
Consider the case of a Person who has an Employeer. Employeer internally maintains all of its employees in a vector< shared_ptr< Person > >. Because of this, do best practices dictate that any interface involving Person should be a shared_ptr wrapped person?
For example, are all or only some of these ok:
Person Employeer::getPresidentCopy();
Person& Employeer::getPresidentRef();
Person* Employeer::getPresidentRawPtr();
shared_ptr<Person> Employeer::getPresidentSharedPtr();
Or for example:
void Employeer::hireByCopy(Person p);
void Employeer::hireByRef(Person& p);
void Employeer::hireByRawPtr(Person* p);
void Employeer::hireBySharedPtr(shared_ptr<Person> p);
If I later want to change the implementation to use johns_very_own_shared_ptr instead of the boost variety, am I trapped in the old implementation?
On the other hand, if I expose raw pointers or references from the interface, do I risk someone deleting the memory out from under the shared_ptr? Or do I risk the shared_ptr being deleted and making my reference invalid?
See my new question for an example involving this.
For example, are all or only some of these ok:
It depends on what you're trying to accomplish. Why does the vector hold shared_ptrs instead of just directly storing Person s by value? (And have you considered boost::ptr_vector?)
You should also consider that maybe what you really ought to hand out is a weak_ptr.
If I later want to change the implementation to use johns_very_own_shared_ptr instead of the boost variety, am I trapped in the old implementation?
Pretty much, but it's not impossible to fix. (I suspect that in C++0x, liberal use of the auto keyword will make this easier to deal with, since you won't have to modify the calling code as much, even if it didn't use typedef s.) But then, why would you ever want to do that?
On the other hand, if I expose raw pointers or references from the interface, do I risk someone deleting the memory out from under the shared_ptr?
Yes, but that's not your problem. People can extract a raw pointer from a shared_ptr and delete it, too. But if you want to avoid making things needlessly unsafe, don't return raw pointers here. References are much better because nobody ever figures they're supposed to delete &reference_received_from_api;. (I hope so, anyway ^^;;;; )
I would introduce a typedef and insulate myself against changes. Something like this:
typedef std::shared_ptr<Person> PersonPtr;
PersonPtr Employeer::getPresident() const;
I place typedefs like this one in a (just one) header together with forward declarations. This makes it easy to change if I would ever want to.
You don't have to hand out shared_ptr, but if you hand out raw pointers you run the risk of some raw pointer persisting after the object has been destroyed.
With fatal consequences.
So, handing out references generally OK (if client code takes address then that's no more your fault than if client code takes address of *shared_ptr), but raw pointers, think first.
Cheers & hth.,
I shouldn't give user raw pointers, when you use shared_ptrs. User could delete it, what will cause double deletion.
To hide usage of boost:shared_ptr you can use typedef to hide actual type, and use this new type instead.
typedef boost::shared_ptr<Person> Person_sptr;
The only reason to hand out a shared_ptr here is if the lifetime of the returned object reference is not tied directly to the lifetime of its residence in the vector.
If you want somebody to be able to access the Person after they stop being an Employee, then shared_ptr would be appropriate. Say if you are moving the Person to the vector for a different Employer.
I work on a moderately sized project that links in several libraries. Some of those libraries have their own memory management subsystems (APR, MFC) and really annoy me. Whether their view of the world is good or bad, it's entirely different from everybody else's and requires a little more code than they otherwise would.
Additionally, those libraries make swapping out malloc or new with jemalloc or the Boehm-Demers-Weiser garbage collector much harder (on Windows it's already hard enough).
I use shared pointers a lot in my own code, but I prefer not to tell others how to manage their memory. Instead, hand out objects whenever possible (letting the library user decide when and how to allocate the memory), and when it's not possible do one of:
hand out raw pointers (plus either a promise that the pointers can be deleted or a Destroy() function to call to deallocate the objects)
accept a function or STL allocator-like argument so you can hook into whatever the user's using for memory management (feel free to default to new and std::allocator)
have your library users hand you allocated memory buffers (like std::vectors)
Using this kind of library doesn't have to be nasty:
// situation (1) from above
std::shared_ptr<Foo> foo(Library_factory::get_Foo(), Library_factory::deallocate);
// situation (2) above (declaration on next line is in a header file)
template<typename allocator=std::allocator<Foo> > Foo* library_function_call();
boost::shared_ptr<Foo> foo = library_function_call();
// situation (3) above, need to fill a buffer of ten objects
std::vector<Foo> foo_buffer(10);
fill_buffer(&foo_buffer[0], foo_buffer.size());
Related
I'm having trouble getting things organized properly with smart pointers. Almost to the point that I feel compelled to go back to using normal pointers.
I would like to make it easy to use smart pointers throughout the program without having to type shared_ptr<...> every time. One solution I think of right away is to make a template class and add a typedef sptr to it so I can do class Derived : public Object < Derived > .. and then use Derived::sptr = ... But this obviously is horrible because it does not work with another class that is then derived from Derived object.
And even doing typedef shared_ptr<..> MyObjectPtr is horrible because then it needs to be done for each kind of smart pointer for consistency's sake, or at least for unique_ptr and shared_ptr.
So what's the standard way people use smart pointers? Because frankly I'm starting to see it as being too much hassle to use them. :/
So what's the standard way people use smart pointers?
Rarely. The fact that you find it a hassle to use them is a sign that you over-use pointers. Try to refactor your code to make pointers the exception, not the rule. shared_ptr in particular has its niche, but it’s a small one: namely, when you genuinely have to share ownership of a resource between several objects. This is a rare situation.
Because frankly I'm starting to see it as being too much hassle to use them. :/
Agreed. That’s the main reason not to use pointers.
There are more ways to avoid pointers. In particular, shared_ptr really only needs to spelled out when you actually need to pass ownership. In functions which don’t deal with ownership, you wouldn’t pass a shared_ptr, or a raw pointer; you would pass a reference, and dereference the pointer upon calling the function.
And inside functions you almost never need to spell out the type; for instance, you can (and should) simply say auto x = …; instead of shared_ptr<Class> x = …; to initialise variables.
In summary, you should only need to spell out shared_ptr in very few places in your code.
I have a lot of code that creates objects dynamically. So using pointers is necessary because the number of objects is not known from the start. An object is created in one subsystem, then stored in another, then passed for further processing to the subsystem that created it. So that I guess means using shared_ptr. Good design? I don't know, but it seems most logical to ask subsystem to create a concrete object that it owns, return a pointer to an interface for that object and then pass it for further processing to another piece of code that will interact with the object through it's abstract interface.
I could return unique_ptr from factory method. But then I would run into trouble if I need to pass the object for processing multiple times. Because I would still need to know about the object after I pass it to another method and unique_ptr would mean that I lose track of the object after doing move(). Since I need to have at least two references to the object this means using shared_ptr.
I heard somewhere that most commonly used smart pointer is unique_ptr. Certainly not so in my application. I end up with using shared_ptr mush more often. Is this a sign of bad design then?
I am trying to write a simple game using C++ and SDL. My question is, what is the best practice to store class member variables.
MyObject obj;
MyObject* obj;
I read a lot about eliminating pointers as much as possible in similar questions, but I remember that few years back in some books I read they used it a lot (for all non trivial objects) . Another thing is that SDL returns pointers in many of its functions and therefor I would have to use "*" a lot when working with SDL objects.
Also am I right when I think the only way to initialize the first one using other than default constructor is through initializer list?
Generally, using value members is preferred over pointer members. However, there are some exceptions, e.g. (this list is probably incomplete and only contains reason I could come up with immediately):
When the members are huge (use sizeof(MyObject) to find out), the difference often doesn't matter for the access and stack size may be a concern.
When the objects come from another source, e.g., when there are factory function creating pointers, there is often no alternative to store the objects.
If the dynamic type of the object isn't known, using a pointer is generally the only alternative. However, this shouldn't be as common as it often is.
When there are more complicated relations than direct owner, e.g., if an object is shared between different objects, using a pointer is the most reasonable approach.
In all of these case you wouldn't use a pointer directly but rather a suitable smart pointer. For example, for 1. you might want to use a std::unique_ptr<MyObject> and for 4. a std::shared_ptr<MyObject> is the best alternative. For 2. you might need to use one of these smart pointer templates combined with a suitable deleter function to deal with the appropriate clean-up (e.g. for a FILE* obtained from fopen() you'd use fclose() as a deleter function; of course, this is a made up example as in C++ you would use I/O streams anyway).
In general, I normally initialize my objects entirely in the member initializer list, independent on how the members are represented exactly. However, yes, if you member objects require constructor arguments, these need to be passed from a member initializer list.
First I would like to say that I completely agree with Dietmar Kühl and Mats Petersson answer. However, you have also to take on account that SDL is a pure C library where the majority of the API functions expect C pointers of structs that can own big chunks of data. So you should not allocate them on stack (you shoud use new operator to allocate them on the heap). Furthermore, because C language does not contain smart pointers, you need to use std::unique_ptr::get() to recover the C pointer that std::unique_ptr owns before sending it to SDL API functions. This can be quite dangerous because you have to make sure that the std::unique_ptr does not get out of scope while SDL is using the C pointer (similar problem with std::share_ptr). Otherwise you will get seg fault because std::unique_ptr will delete the C pointer while SDL is using it.
Whenever you need to call pure C libraries inside a C++ program, I recommend the use of RAII. The main idea is that you create a small wrapper class that owns the C pointer and also calls the SDL API functions for you. Then you use the class destructor to delete all your C pointers.
Example:
class SDLAudioWrap {
public:
SDLAudioWrap() { // constructor
// allocate SDL_AudioSpec
}
~SDLAudioWrap() { // destructor
// free SDL_AudioSpec
}
// here you wrap all SDL API functions that involve
// SDL_AudioSpec and that you will use in your program
// It is quite simple
void SDL_do_some_stuff() {
SDL_do_some_stuff(ptr); // original C function
// SDL_do_some_stuff(SDL_AudioSpec* ptr)
}
private:
SDL_AudioSpec* ptr;
}
Now your program is exception safe and you don't have the possible issue of having smart pointers deleting your C pointer while SDL is using it.
UPDATE 1: I forget to mention that because SDL is a C library, you will need a custom deleter class in order to proper manage their C structs using smart pointers.
Concrete example: GSL GNU scientific library. Integration routine requires the allocation of a struct called "gsl_integration_workspace". In this case, you can use the following code to ensure that your code is exception safe
auto deleter= [](gsl_integration_workspace* ptr) {
gsl_integration_workspace_free(ptr);
};
std::unique_ptr<gsl_integration_workspace, decltype(deleter)> ptr4 (
gsl_integration_workspace_alloc (2000), deleter);
Another reason why I prefer wrapper classes
In case of initialization, it depends on what the options are, but yes, a common way is to use an initializer list.
The "don't use pointers unless you have to" is good advice in general. Of course, there are times when you have to - for example when an object is being returned by an API!
Also, using new will waste quite a bit of memory and CPU-time if MyObject is small. Each object created with new has an overhead of around 16-48 bytes in a typical modern OS, so if your object is only a couple of simple types, then you may well have more overhead than actual storage. In a largeer application, this can easily add up to a huge amount. And of course, a call to new or delete will most likely take some hundreds or thousands of cycles (above and beyond the time used in the constructor). So, you end up with code that runs slower and takes more memory - and of course, there's always some risk that you mess up and have memory leaks, causing your program to potentially crash due to out of memory, when it's not REALLY out of memory.
And as that famous "Murphy's law states", these things just have to happen at the worst possible and most annoying times - when you have just done some really good work, or when you've just succeeded at a level in a game, or something. So avoiding those risks whenever possible is definitely a good idea.
Well, creating the object is a lot better than using pointers because it's less error prone. Your code doesn't describe it well.
MyObj* foo;
foo = new MyObj;
foo->CanDoStuff(stuff);
//Later when foo is not needed
delete foo;
The other way is
MyObj foo;
foo.CanDoStuff(stuff);
less memory management but really it's up to you.
As the previous answers claimed the "don't use pointers unless you have to" is a good advise for general programming but then there are many issues that could finally make you select the pointers choice. Furthermore, in you initial question you are not considering the option of using references. So you can face three types of variable members in a class:
MyObject obj;
MyObject* obj;
MyObject& obj;
I use to always consider the reference option rather than the pointer one because you don't need to take care about if the pointer is NULL or not.
Also, as Dietmar Kühl pointed, a good reason for selecting pointers is:
If the dynamic type of the object isn't known, using a pointer is
generally the only alternative. However, this shouldn't be as common
as it often is.
I think this point is of particular importance when you are working on a big project. If you have many own classes, arranged in many source files and you use them in many parts of your code you will come up with long compilation times. If you use normal class instances (instead of pointers or references) a simple change in one of the header file of your classes will infer in the recompilation of all the classes that include this modified class. One possible solution for this issue is to use the concept of Forward declaration, which make use of pointers or references (you can find more info here).
I currently have vectors such as:
vector<MyClass*> MyVector;
and I access using
MyVector[i]->MyClass_Function();
I would like to make use of shared_ptr. Does this mean all I have to do is change my vector to:
typedef shared_ptr<MyClass*> safe_myclass
vector<safe_myclass>
and I can continue using the rest of my code as it was before?
vector<shared_ptr<MyClass>> MyVector; should be OK.
But if the instances of MyClass are not shared outside the vector, and you use a modern C++11 compiler, vector<unique_ptr<MyClass>> is more efficient than shared_ptr (because unique_ptr doesn't have the ref count overhead of shared_ptr).
Probably just std::vector<MyClass>. Are you
working with polymorphic classes or
can't afford copy constructors or have a reason you can't copy and are sure this step doesn't get written out by the compiler?
If so then shared pointers are the way to go, but often people use this paradigm when it doesn't benefit them at all.
To be complete if you do change to std::vector<MyClass> you may have some ugly maintenance to do if your code later becomes polymorphic, but ideally all the change you would need is to change your typedef.
Along that point, it may make sense to wrap your entire std::vector.
class MyClassCollection {
private : std::vector<MyClass> collection;
public : MyClass& at(int idx);
//...
};
So you can safely swap out not only the shared pointer but the entire vector. Trade-off is harder to input to APIs that expect a vector, but those are ill-designed as they should work with iterators which you can provide for your class.
Likely this is too much work for your app (although it would be prudent if it's going to be exposed in a library facing clients) but these are valid considerations.
Don't immediately jump to shared pointers. You might be better suited with a simple pointer container if you need to avoid copying objects.
In a new piece of code I have several different classes that refer to each other. Something like this (this is not my actual situation but an example of something similar):
class BookManager
{
...
};
class Book
{
public:
void setBookManager(BookManager *bookManager) {m_bookManager = bookManager;}
private:
BookManager *m_bookManager;
};
Every book refers to a book manager, but the problem is that many books will have its own specific BookManager, but some books may share a common BookManager.
The caller doesn't really specify what the Book should do with its BookManager, but in about 90% of the cases, the BookManager can be destroyed together with the Book. In about 10% of the cases, the same BookManager is reused for multiple books, and the BookManager must not be deleted with the Book.
Deleting the BookManager together with the Book is handy in those 90% of the cases, as the caller of Book::setBookManager doesn't need to remember the BookManager anymore. It just dies with the Book itself.
I see two alternative solutions for solving this.
First is to make extensive use of shared pointers. If the caller is not interested anymore in the BookManager afterwards, it doesn't keep a shared pointer to it. If it is still interested in it, or if it wants the BookManager to be shared over multiple books, it keeps the shared pointer and passes it to those multiple books.
A second alternative is to tell the Book explicitly what to do with the ownership of the book, like this:
class Book
{
public:
void setBookManager(BookManager *bookManager, book takeOwnership=true)
{
m_bookManager = bookManager;
m_hasOwnership = takeOwnership;
}
~Book()
{
if (m_hasOwnership && m_bookManager) delete m_bookManager;
}
private:
BookManager *m_bookManager;
bool m_hasOwnership;
};
The second solution seems much easier and allows us to use normal pointer syntax (BookManager * as opposed to std::shared_ptr<BookManager>), but it seems less 'clean' than the shared pointer approach.
Another alternative might be to have a typedef in BookManager like this:
class BookManager
{
public:
typedef std::shared_ptr<BookManager> Ptr;
...
};
Which allows us to write this:
BookManager::Ptr bookManager;
Which looks more like the the normal pointer-syntax than the original shared pointer syntax.
Does anyone have experience with either approach?
Any other suggestions?
In C++ if you have shared, un-coordinated access to common objects then the most common approach is some kind of reference counting, which you get from shared_ptr.
The only downside is that it isn't pervasive in C++ (especially libraries), so you sometimes need access to the raw pointer. In those cases, you need to be careful to keep the object alive.
I suggest that if you used shared_ptr -- try to use it everywhere, unless it's impossible. And yes, use the typedef if you want.
You seem to have this pretty well thought through. Looks like an ideal use for shared_ptr to me.
In the interests of adding SOME value for you, make sure you look at the templates for efficient shared_ptr creation here.
There are 2 kinds of "ownership" in C++:
deterministic ownership: at any moment you can point who is responsible for the resource
shared ownership: at any moment there might be several owners, they are hard to pinpoint though
shared_ptr, as the name implies, is for the second case. It is rarely required, especially with the introduction of move semantics and thus unique_ptr, but in those cases where it is actually required, it's invaluable.
Looking at your case, the question I have is: do you actually need shared ownership ?
One typical solution to avoid shared ownership is to use a Factory, which will be the sole owner of all the objects it creates, and guarantees they are alive as long the Factory itself is alive.
It might be "less safe" than using a shared_ptr, but there are very interesting arguments:
the lifetime of the objects is deterministic once more, much easier to debug
there is no risk of creating a cycle of references (and leaking memory) by accident
Unless you are memory constrained (in which case the sooner the objects get deleted the better it is), you might wish to take a BookManagerFactory approach here.
Only when you know exactly where the object is owned and take care to delete it there (!), should you use bare pointers. I have a "stack" of classes that each hold unique parent pointer, in which case the reference count would always be 1 and you can access the deepest element through the last child. It seems like you have a much more complicated setup here, though, go with smart pointers. Remember that even if a bare pointer might seem cleaner or easier, unique_ptr should be recommended, but you might have to battle move vs copy assignment in pre-conversion code and cryptic error messages resulting from the switch.
Lou Franco already gave you the answer, but as a side note: Your second implementation idea is essentially what an auto_ptr does (when take ownership is true).
A better solution might be to have the Book class hold a handle (e.g. array index or hash) to a BookManager that residese in some BookManagerCache class. The Cache class is solely responsible for managing the lifetimes of BookManagers.
I've been evaluating various smart pointer implementations (wow, there are a LOT out there) and it seems to me that most of them can be categorized into two broad classifications:
1) This category uses inheritance on the objects referenced so that they have reference counts and usually up() and down() (or their equivalents) implemented. IE, to use the smart pointer, the objects you're pointing at must inherit from some class the ref implementation provides.
2) This category uses a secondary object to hold the reference counts. For example, instead of pointing the smart pointer right at an object, it actually points at this meta data object... Who has a reference count and up() and down() implementations (and who usually provides a mechanism for the pointer to get at the actual object being pointed to, so that the smart pointer can properly implement operator ->()).
Now, 1 has the downside that it forces all of the objects you'd like to reference count to inherit from a common ancestor, and this means that you cannot use this to reference count objects that you don't have control over the source code to.
2 has the problem that since the count is stored in another object, if you ever have a situation that a pointer to an existing reference counted object is being converted into a reference, you probably have a bug (I.E., since the count is not in the actual object, there is no way for the new reference to get the count... ref to ref copy construction or assignment is fine, because they can share the count object, but if you ever have to convert from a pointer, you're totally hosed)...
Now, as I understand it, boost::shared_pointer uses mechanism 2, or something like it... That said, I can't quite make up my mind which is worse! I have only ever used mechanism 1, in production code... Does anyone have experience with both styles? Or perhaps there is another way thats better than both of these?
"What is the best way to implement smart pointers in C++"
Don't! Use an existing, well tested smart pointer, such as boost::shared_ptr or std::tr1::shared_ptr (std::unique_ptr and std::shared_ptr with C++ 11)
If you have to, then remember to:
use safe-bool idiom
provide an operator->
provide the strong exception guarantee
document the exception requirements your class makes on the deleter
use copy-modify-swap where possible to implement the strong exception guarantee
document whether you handle multithreading correctly
write extensive unit tests
implement conversion-to-base in such a way that it will delete on the derived pointer type (policied smart pointers / dynamic deleter smart pointers)
support getting access to raw pointer
consider cost/benifit of providing weak pointers to break cycles
provide appropriate casting operators for your smart pointers
make your constructor templated to handle constructing base pointer from derived.
And don't forget anything I may have forgotten in the above incomplete list.
Just to supply a different view to the ubiquitous Boost answer (even though it is the right answer for many uses), take a look at Loki's implementation of smart pointers. For a discourse on the design philosophy, the original creator of Loki wrote the book Modern C++ Design.
I've been using boost::shared_ptr for several years now and while you are right about the downside (no assignment via pointer possible), I think it was definitely worth it because of the huge amount of pointer-related bugs it saved me from.
In my homebrew game engine I've replaced normal pointers with shared_ptr as much as possible. The performance hit this causes is actually not so bad if you are calling most functions by reference so that the compiler does not have to create too many temporary shared_ptr instances.
Boost also has an intrusive pointer (like solution 1), that doesn't require inheriting from anything. It does require changing the pointer to class to store the reference count and provide appropriate member functions. I've used this in cases where memory efficiency was important, and didn't want the overhead of another object for each shared pointer used.
Example:
class Event {
public:
typedef boost::intrusive_ptr<Event> Ptr;
void addRef();
unsigned release();
\\ ...
private:
unsigned fRefCount;
};
inline void Event::addRef()
{
fRefCount++;
}
inline unsigned Event::release(){
fRefCount--;
return fRefCount;
}
inline void intrusive_ptr_add_ref(Event* e)
{
e->addRef();
}
inline void intrusive_ptr_release(Event* e)
{
if (e->release() == 0)
delete e;
}
The Ptr typedef is used so that I can easily switcth between boost::shared_ptr<> and boost::intrusive_ptr<> without changing any client code
If you stick with the ones that are in the standard library you will be fine.
Though there are a few other types than the ones you specified.
Shared: Where the ownership is shared between multiple objects
Owned: Where one object owns the object but transfer is allowed.
Unmovable: Where one object owns the object and it can not be transferred.
The standard library has:
std::auto_ptr
Boost has a couple more than have been adapted by tr1 (next version of the standard)
std::tr1::shared_ptr
std::tr1::weak_ptr
And those still in boost (which in relatively is a must have anyway) that hopefully make it into tr2.
boost::scoped_ptr
boost::scoped_array
boost::shared_array
boost::intrusive_ptr
See:
Smart Pointers: Or who owns you baby?
It seems to me this question is kind of like asking "Which is the best sort algorithm?" There is no one answer, it depends on your circumstances.
For my own purposes, I'm using your type 1. I don't have access to the TR1 library. I do have complete control over all the classes I need to have shared pointers to. The additional memory and time efficiency of type 1 might be pretty slight, but memory usage and speed are big issues for my code, so type 1 was a slam dunk.
On the other hand, for anyone who can use TR1, I'd think the type 2 std::tr1::shared_ptr class would be a sensible default choice, to be used whenever there isn't some pressing reason not to use it.
The problem with 2 can be worked around. Boost offers boost::shared_from_this for this same reason. In practice, it's not a big problem.
But the reason they went with your option #2 is that it can be used in all cases. Relying on inheritance isn't always an option, and then you're left with a smart pointer you can't use for half your code.
I'd have to say #2 is best, simply because it can be used in any circumstances.
Our project uses smart pointers extensively. In the beginning there was uncertainty about which pointer to use, and so one of the main authors chose an intrusive pointer in his module and the other a non-intrusive version.
In general, the differences between the two pointer types were not significant. The only exception being that early versions of our non-intrusive pointer implicitly converted from a raw pointer and this can easily lead to memory problems if the pointers are used incorrectly:
void doSomething (NIPtr<int> const &);
void foo () {
NIPtr<int> i = new int;
int & j = *i;
doSomething (&j); // Ooops - owned by two pointers! :(
}
A while ago, some refactoring resulted in some parts of the code being merged, and so a choice had to be made about which pointer type to use. The non-intrusive pointer now had the converting constructor declared as explicit and so it was decided to go with the intrusive pointer to save on the amount of code change that was required.
To our great surprise one thing we did notice was that we had an immediate performance improvement by using the intrusive pointer. We did not put much research into this, and just assumed that the difference was the cost of maintaining the count object. It is possible that other implementations of non-intrusive shared pointer have solved this problem by now.
What you are talking about are intrusive and non-intrusive smart pointers. Boost has both. boost::intrusive_ptr calls a function to decrease and increase the reference count of your object, everytime it needs to change the reference count. It's not calling member functions, but free functions. So it allows managing objects without the need to change the definition of their types. And as you say, boost::shared_ptr is non-intrusive, your category 2.
I have an answer explaining intrusive_ptr: Making shared_ptr not use delete. In short, you use it if you have an object that has already reference counting, or need (as you explain) an object that is already referenced to be owned by an intrusive_ptr.