Chapter 4 covers the difference between the smart pointer (Ptr) and the raw pointer (*) thoroughly. But I think I see what your crash issue might be. The crash is usually due to the raw pointer getting freed by a smart pointer going out of scope when there aren’t enough reference counts for it. The solution you came up with (to return a smart pointer) works because returning a smart pointer from CreateInstance would add a reference count to the object, thus preventing it from getting freed. It might also leak the object, so isn’t necessary. You might have been led astray by a typo I just noticed in the Chapter 12 documentation.
Based on a code snippet you included in a different post, I think you are doing this *inside* you CreateInstance() function:
IFormatServiceCallbackPtr p = new CBaseObject< MyFormatImplementation >();
I actually see that this is what the sample code in Chapter 12 says to do, but that’s incorrect (we’ll log a bug about this typo). The line should read:
IFormatServiceCallback* p = new CBaseObject< MyFormatImplementation >();
and if you look at the comments in that sample code just after this statement, it actually says, “note that we didn’t use a smart pointer above,” when in fact we accidentally did.
Normally, you want to use smart pointers since they do all the reference counting for you. The exception are in cases like CreateInstance() where you are generating an object for a caller who you expect will do that reference counting. In other words, CreateInstance() just creates the raw pointer and returns the raw pointer, but not reference counted. The function that calls CreateInstance(), however, is obliged to assign the result to a smart pointer thus providingt the first reference count. So use the line above *in* CreateInstance(), and use the line below when *calling* CreateInstance():
IFormatServiceCallbackPtr pMyCallback = MyFormatImplementation::CreateInstance( /* your params here */ );
What is happening in your CreateInstance() function right now is that the raw pointer is being assigned to a smart pointer, which gives it a reference count of 1. But when your CreateInstance() function finishes, that smart pointer goes out of scope, which frees the raw pointer in it (since it had only that one reference count). So by the time you actually return out of CreateInstance() back to the place where it is being assigned to a variable, your callback object has already been freed. Then when you use it later, it crashes because it doesn’t actually exist anymore.
Whether this works or not, I always recommend that everyone read Chapter 4, even if they don’t read anything else. That chapter covers in great detail the differences between the smart pointer (Ptr) and the raw pointer (*) and covers the various reasons why not handling these types quite right can lead to memory leaks or crashes.
Hope this helps.