COM Reference Counting Questions - c++

I am writing code that utilizes COM interfaces. I am basing my code on examples that I have found online. I do not want to utilize smart pointers in this case because I want to understand the basics of COM and not just have a smart pointer class do all of the work for me.
In order to frame my questions, let's assume I have a class similar to the following:
public class TestClass
{
private:
IUnknown *m_pUnknown;
public:
TestClass();
void AssignValue();
}
TestClass::TestClass()
{
m_pUnknown = NULL;
}
void TestClass::AssignValue()
{
IUnknown *pUnknown = NULL;
//Assign value to pUnknown here - not relevant to my questions
m_pUnknown = pUnknown;
pUnknown->Release();
}
Now on to my specific questions.
1) The examples I've seen to not use AddRef() when initializing a value, such as in the class constructor. Does the AddRef() happen "automatically" behind the scenes when a COM pointer is first assigned a value?
2) Although my code example does not show it, it is my understanding that in the AssignValue() method, when you assign a second value to overwrite the value of pUnknown (originally set in the class constructor), Release() is automatically called. After assigning the new value to pUnknown its reference count stands at zero. I need to call pUnknown->AddRef() immediately after the reassignment. Is my understanding correct?

Notes: I assume we are ignoring exceptions for simplicity here. If this was for real, you would want to use smart pointers to help keep things straight in the presence of exceptions. Similarly, I am not worrying about proper copying or destruction of instances of your example class or multi-threading. (Your raw pointers cannot be used from different threads as simply as you might assume.)
First, You need to make any necessary calls to COM. The only way anything might happen "automatically" behind the scenes would be if you were using smart pointers to do them.
1) The examples you refer to have to be getting their COM interface pointers from somewhere. This would be by making COM calls, e.g., CoCreateInstance() and QueryInterface(). These calls are passed the address of your raw pointer and set that raw pointer to the appropriate value. If they weren't also implicitly AddRef'ed, the reference count might be 0 and COM could delete the associated COM object before your program could do anything about it. So such COM calls must include an implicit AddRef() on your behalf. You are responsible for a Release() to match this implicit AddRef() that you instigated with one of these other calls.
2a) Raw pointers are raw pointers. Their value is garbage until you arrange for them to be set to something valid. In particular, assigning a value to one will NOT auto-magically call a function. Assigning to a raw pointer to an interface does not call Release() - you need to do that at the appropriate time. In your post, it appears that you are "overwriting" a raw pointer that had previously been set to NULL, hence there was no existing COM interface instance in the picture. There could not have been an AddRef() on something that doesn't exist, and must not be a Release() on something that isn't there.
2b)
Some of the code you indicated by a comment in your example is very relevant, but can easily be inferred. You have a local raw pointer variable, pUnknown. In the absent code, you presumably use a COM call that obtains an interface pointer, implicitly AddRefs it, and fills in your raw pointer with the proper value to use it. This gives you the responsibility for one corresponding Release() when you are done with it.
Next, you set a member raw pointer variable (m_pUnknown) with this same value. Depending on the previous use of this member variable, you might have needed to call Release() with its former value before doing this.
You now have 2 raw pointers set to the value to work with this COM interface instance and responsibility for one Release() due to 1 implicit AddRef() call. There are two ways to deal with this, but neither is quite what you have in your sample.
The first, most straightforward, and proper approach (which others have correctly pointed out & I skipped passed in the first version of this answer) is one AddRef() and one Release() per pointer. Your code is missing this for m_pUnknown. This requires adding m_pUnknown->AddRef() immediately after the assignment to m_pUnknown and 1 corresponding call to Release() "someplace else" when you are done using the current interface pointer from m_pUnknown. One usual candidate for this "someplace else" in your code is in the class destructor.
The second approach is more efficient, but less obvious. Even if you decide not to use it, you may see it, so should at least be aware of it. Following the first approach you would have the code sequence:
m_pUnknown = pUnknown;
m_pUnknown->AddRef();
pUnknown->Release();
Since pUnknown and m_pUnknown are set the same here, the Release() is immediately undoing the AddRef(). In this circumstance, eliding this AddRef/Release pair is reference count neutral and saves 2 round trips into COM. My mental model for this is a transfer of the interface and reference count from one pointer to the other. (With smart pointers it would look like newPtr.Attach( oldPtr.Detach() ); ) This approach leaves you with the original/not shown implicit AddRef() and needing to add the same m_pUnknown->Release() "someplace else" as in the first alternative.
In either approach, you exactly match AddRefs (implicit or explicit) with Releases for each interface and never go to a 0 reference count until you are done with the interface. Once you do hit 0, you do not attempt to use the value in the pointer.

Avi Berger already posted a great answer, but here is the same thing stated another way in case it helps with understanding.
In COM, reference counting is done within the COM object. The COM runtime will destruct and free an object whose reference count reaches 0. (This might be delayed by some time from the point of the count hitting 0).
Everything else is a convention. The usual convention amongst C++ COM programmers is that raw interface pointers should be treated as owning pointers. This concept means that any time a pointer points to a COM object, the pointer owns that object.
Using this terminology, the object may have multiple owners at any one time, and the object will be destroyed when nobody owns it.
However, raw pointers in C++ don't have ownership semantics built in. So you have to implement it yourself by making function calls:
Call AddRef on an interface pointer when that pointer takes ownership of an object. (You'll need to be aware of which Windows API functions or other library functions already do this, to avoid you doing it twice)
Call Release on an interface pointer when that pointer is about to stop owning an object.
The benefit of smart pointers is that they make it impossible for you to forget to call Release when an interface pointer stops owning an object. This includes the following cases:
Pointer goes out of scope.
Pointer is made to stop pointing to the object, by using assignment operator.
So, looking at your sample code. You have the pointer m_pUnknown. You want this pointer to take ownership of the object, so the code should be:
m_pUnknown = pUnknown;
m_pUnknown->AddRef();
You will also need to add code to your class destructor and your class assignment operator to call m_pUnknown->Release(). I would very strongly recommend wrapping these calls in the smallest class possible (that is, write your own smart pointer and make TestClass have that smart pointer as a member variable). Assuming of course you don't want to use an existing COM smart pointer class for pedagogical reasons.
The call pUnknown->Release(); is correct because pUnknown currently owns the object, and the pointer is about to stop owning the object due to the fact that it will be destroyed when the function block ends.
You may observe that it would be possible to remove both of the lines m_pUnknown->AddRef() and pUnknown->Release(). The code will behave exactly the same. However , it is better to follow the convention outlined above. Sticking to a convention helps yourself to avoid errors and it also helps other coders to understand your code.
To put it another way, the usual convention is to think of the pointer as having a reference count of either 0 or 1, even though the reference counting is not actually implemented that way.

First, my apologies. My attempt to simplify my code for the sake of clarity turned out to be misguided. However, I believe my questions were answered. If I may, I will summarize.
1) Any COM object that is assigned a value other than NULL needs to be immediately followed by AddRef() unless the AddRef() was implicitly handled (as is the case with some Windows API calls).
2) Any reassignment of value to a COM pointer, assuming that the "before" value is not NULL must be immediately proceeded by Release(). AddRef() would then by needed as mentioned in #1.
3) Any COM variable whose value needs to be preserved beyond its current scope requires that it have a reference count of at least 1 upon exiting its said scope. This may mean that an AddRef() is required.
Would this be a fair summary? Did I miss anything?

Related

How to pass std::unique_ptr around?

I am having my first attempt at using C++11 unique_ptr; I am replacing a polymorphic raw pointer inside a project of mine, which is owned by one class, but passed around quite frequently.
I used to have functions like:
bool func(BaseClass* ptr, int other_arg) {
bool val;
// plain ordinary function that does something...
return val;
}
But I soon realized that I wouldn't be able to switch to:
bool func(std::unique_ptr<BaseClass> ptr, int other_arg);
Because the caller would have to handle the pointer ownership to the function, what I don't want to. So, what is the best solution to my problem?
I though of passing the pointer as reference, like this:
bool func(const std::unique_ptr<BaseClass>& ptr, int other_arg);
But I feel very uncomfortable in doing so, firstly because it seems non instinctive to pass something already typed as _ptr as reference, what would be a reference of a reference. Secondly because the function signature gets even bigger. Thirdly, because in the generated code, it would be necessary two consecutive pointer indirections to reach my variable.
If you want the function to use the pointee, pass a reference to it. There's no reason to tie the function to work only with some kind of smart pointer:
bool func(BaseClass& base, int other_arg);
And at the call site use operator*:
func(*some_unique_ptr, 42);
Alternatively, if the base argument is allowed to be null, keep the signature as is, and use the get() member function:
bool func(BaseClass* base, int other_arg);
func(some_unique_ptr.get(), 42);
The advantage of using std::unique_ptr<T> (aside from not having to remember to call delete or delete[] explicitly) is that it guarantees that a pointer is either nullptr or it points to a valid instance of the (base) object. I will come back to this after I answer your question, but the first message is DO use smart pointers to manage the lifetime of dynamically allocated objects.
Now, your problem is actually how to use this with your old code.
My suggestion is that if you don't want to transfer or share ownership, you should always pass references to the object. Declare your function like this (with or without const qualifiers, as needed):
bool func(BaseClass& ref, int other_arg) { ... }
Then the caller, which has a std::shared_ptr<BaseClass> ptr will either handle the nullptr case or it will ask bool func(...) to compute the result:
if (ptr) {
result = func(*ptr, some_int);
} else {
/* the object was, for some reason, either not created or destroyed */
}
This means that any caller has to promise that the reference is valid and that it will continue to be valid throughout the execution of the function body.
Here is the reason why I strongly believe you should not pass raw pointers or references to smart pointers.
A raw pointer is only a memory address. Can have one of (at least) 4 meanings:
The address of a block of memory where your desired object is located. (the good)
The address 0x0 which you can be certain is not dereferencable and might have the semantics of "nothing" or "no object". (the bad)
The address of a block of memory which is outside of the addressable space of your process (dereferencing it will hopefully cause your program to crash). (the ugly)
The address of a block of memory which can be dereferenced but which doesn't contain what you expect. Maybe the pointer was accidentally modified and now it points to another writable address (of a completely other variable within your process). Writing to this memory location will cause lots of fun to happen, at times, during the execution, because the OS will not complain as long as you are allowed to write there. (Zoinks!)
Correctly using smart pointers alleviates the rather scary cases 3 and 4, which are usually not detectable at compile time and which you generally only experience at runtime when your program crashes or does unexpected things.
Passing smart pointers as arguments has two disadvantages: you cannot change the const-ness of the pointed object without making a copy (which adds overhead for shared_ptr and is not possible for unique_ptr), and you are still left with the second (nullptr) meaning.
I marked the second case as (the bad) from a design perspective. This is a more subtle argument about responsibility.
Imagine what it means when a function receives a nullptr as its parameter. It first has to decide what to do with it: use a "magical" value in place of the missing object? change behavior completely and compute something else (which doesn't require the object)? panic and throw an exception? Moreover, what happens when the function takes 2, or 3 or even more arguments by raw pointer? It has to check each of them and adapt its behavior accordingly. This adds a whole new level on top of input validation for no real reason.
The caller should be the one with enough contextual information to make these decisions, or, in other words, the bad is less frightening the more you know. The function, on the other hand, should just take the caller's promise that the memory it is pointed to is safe to work with as intended. (References are still memory addresses, but conceptually represent a promise of validity.)
I agree with Martinho, but I think it is important to point out the ownership semantics of a pass-by-reference. I think the correct solution is to use a simple pass-by-reference here:
bool func(BaseClass& base, int other_arg);
The commonly accepted meaning of a pass-by-reference in C++ is like as if the caller of the function tells the function "here, you can borrow this object, use it, and modify it (if not const), but only for the duration of the function body." This is, in no way, in conflict with the ownership rules of the unique_ptr because the object is merely being borrowed for a short period of time, there is no actual ownership transfer happening (if you lend your car to someone, do you sign the title over to him?).
So, even though it might seem bad (design-wise, coding practices, etc.) to pull the reference (or even the raw pointer) out of the unique_ptr, it actually is not because it is perfectly in accordance with the ownership rules set by the unique_ptr. And then, of course, there are other nice advantages, like clean syntax, no restriction to only objects owned by a unique_ptr, and so.
Personally, I avoid pulling a reference from a pointer/smart pointer. Because what happens if the pointer is nullptr? If you change the signature to this:
bool func(BaseClass& base, int other_arg);
You might have to protect your code from null pointer dereferences:
if (the_unique_ptr)
func(*the_unique_ptr, 10);
If the class is the sole owner of the pointer, the second of Martinho's alternative seems more reasonable:
func(the_unique_ptr.get(), 10);
Alternatively, you can use std::shared_ptr. However, if there's one single entity responsible for delete, the std::shared_ptr overhead does not pay off.

How exactly does memory handling (i.e, the function Release) work with Direct3D?

I came across a leak in a Direct3D application of mine, and I ended up correcting it, but I think the cause of the leak was due to my misunderstanding of how Direct3D handles its memory and interfaces.
I haven't been able to find a definitive article/tutorial on it (please provide one if you have one), but from what I've gathered, it works as such:
Every time you call a Get method, the number of references for the object returned is incremented. So if I call GetRenderTarget, the surface being rendered to has its reference count incremented.
Calling Release on the interface decrements its reference count. These first two points combined essentially mean: every time you get an interface, release it after you're done with it.
When the reference count reaches 0, the instance is deleted.
I'm not entirely sure if this is correct, but it seems to work in practice. If someone could clarify/confirm how it works, that'd be great.
P.S, are there any safeguards implemented in releasing interfaces? Calling Release any number of times on the back buffer doesn't seem to do any damage (which is a good thing, but I'm not sure why it doesn't).
Direct3D is based on COM, which is a technology that's at least 15 years old. Seems many people claim COM is dead and for that reason many overlook it, but reality is that there are many things in windows including Direct3D and MS's new Media Foundation that are all based on COM.
I strongly suggest you take a look at general COM programming. There are plenty of books and resources, but many of them are rather old but that's ok because the root of the technology hasn't changed for a very long time.
Basically what you've observed is interface reference counting. COM is based purely on accessing objects via interfaces, which all derive from the base interface, IUnknown. IUnknown implements methods AddRef() and Release() and it is the responsibility of your application to call AddRef() whenever you store a local copy of a pointer and to call Release() whenever that local copy is no longer needed.
When you have methods with interface out parameters (i.e. IFoo** ppObj ), that means the callee is giving you back an interface and now that you have it, it is still your responsibility to call Release() whenever you are done with it.
Once you get the hang of it, I'd suggest you start using CComPtr smart class for storing local and member variables (still pass raw interface values between function calls, no need for smart pointer parameter types). It will take care of all your reference counting. Also don't make it a practice of calling release "any number" of times. It might work today because the object is implemented as a singleton, or maybe something else is holding on to it, but that might change with next patch or next release. Always follow the rules. If you have an interface, when you don't need it call Release() exactly once. If you made a copy of interface pointer, make sure to call AddRef() exactly once.
The application of addref/release semantics is much wider than COM technology. There is simple rule one CreateObject() (or CreateTexture, or GetRenderTarget, or GetBackBuffer, etc...) have to be confronted with one Release(), one AddRef() have to be confronted with one Release().
In COM IUnknown::Release() returns number of references to object. It may delude you and you can think:
"Hm... I just call Release() until it return 0 and I will have no leaks. ???? PROFIT!!!!!111" <-- That is wrong! AddRef might be called by Direct3D itself or by 3rd_party library you pass this object to, or something else outside your app. One Release for one AddRef. You should call Release when you don't need object anymore, don't waste system resources.
You said:
Calling Release any number of times on the back buffer doesn't seem to do any damage
That means nothing. May be The Universe like you so much or you just too lucky to not get exceptions from D3D.
Smart pointers (such as CComPtr) could make your life much easier if you will use them. In this case you don't need to call Release explicitly, it is called in CComPtr dtor if it is assigned to some object.
void get_surface(IDirect3DDevice9 *pDevice)
{
IDirect3DSurface9 *surf0;
IDirect3DSurface9 *surf1;
CComPtr<IDirect3DSurface9> surf2;
CComPtr<IDirect3DSurface9> surf3;
CComPtr<IDirect3DSurface9> surf4;
pDevice->GetRenderTarget( 0, surf0 ); // surface reference counter incremented, you should call Release() for this
surf1 = surf0; // surface reference count is not incremented, you shouldn't call Release() for this
pDevice->GetRenderTarget( 0, surf2 ); // surface reference counter incremented
CComPtr<IDirect3DSurface9> surf3 = surf0; // surface reference counter incremented
surf0->Release(); // release for pDevice->GetRenderTarget( 0, surf0 );
surf2.Release(); // .Release() used not ->Release() - it is important
surf4.Release(); // nothing happens because surf4 == 0
} // surf3.Release() is called in surf3 destructor
Also you may #define D3D_DEBUG_INFObefore including direct 3d headers and switch to debug d3d runtime. It is helpful in finding leaks in d3d app.
May the CComPtr Force be with you.
D3D objects are COM objects, and they use a basic reference counting system to manage the lifetime of the object. (See wikipedia for more info about the Component Object Model, or the MSDN article Managing Object Lifetimes)
The reference count is modified purely through the AddRef/Release methods, and certain other functions call those methods.
Creating the object as well as calling certain Get methods that return an object derived from the IUnknown class will call AddRef internally to increment the reference count, so you will need to call Release for each call when you are finished with the object.
If you pass the object to another function or class that stores a copy of the point (even temporarily) that class/function should call AddRef to ensure that the object is not freed while it is using it (and Release to signal it is done).
When the reference counter reaches 0 from a call to Release the object is signalled that it may be a good time to delete the held resources, but it may not happen immediately. There is also no protection for calling Release multiple times. The reference counter will not become negative, but it will not perform any other sanity checking (because it can't really) so you can cause application instability by trying to release references you don't hold.
Yes, you are correct. This is called reference counting and it ensures that objects are alive as long as they are being used, and no longer. You can use a variety of smart pointers to enforce this rule- both shared_ptr and (C++11) unique_ptr allow for custom deleters to call Release(). This makes it easy to control the lifetime of Direct3D objects just like you would for any other object in your application. You don't need to start including ATL libraries and CComPtr to use smart pointers with COM interfaces.

Deleting a Shared Pointer

I have a pointer to a QScriptEngine that I'm passing through the overloaded class constructor of class Evaluator and assigns it to QScriptEngine *engine_ (class Property subclasses Evaluator, and calls this constructor of Evaluator, passing it an already allocated QScriptEngine). The constructor with no arguments creates the new QScriptEngine pointer (class Generic subclasses Evaluator in this way). In the destructor I test if engine_ is not NULL, delete the pointer, then assign it NULL. Should the pointer (engine_) in the derived Property now also be NULL? Something tells me this is not the case. If not, how do you deal with this situation? I need the QScriptEngine to be the same instance throughout. QScriptEngine's = operator is private, or I would be avoiding the pointer all together.
I saw some info on shared pointers (boost::shared_ptr and std:tr1::shared_ptr) in another SO question. I'm already using boost for the regex library, so boost is not out of the question if that's the best way to deal with this. Hopefully there's a non-boost way, for general C++ knowledge and future projects.
You can solve this by giving one of the classes (class A) lifetime control of that pointer, along with a 'getter' method. The other class (class B) would always call A's getter whenever it needed the pointer. That way, A remains in control of the pointer at all times. Downside is the getter function (it will probably inline, but it's still a second indirection). Also, B is going to have to check that pointer for NULL on pretty much every use.
Your other choice is to wrap the pointer in something like boost::shared_ptr which takes care of the problem (if used properly) by holding the underlying pointer, and only deleting it when all objects that share that pointer are deleted. You could write this yourself, but since you already have boost in play, I'd just use their implementation.
A third choice is to re-factor the whole thing so that you don't need a shared pointer. I'd personally never design a C++ program that needed shared pointers, just because it's a spot where memory management bugs could easily creep in over the years, but that's just me.

what is difference between allocating pointer object by the following 2 ways?

I have created a COM componenet named as Test.dll in that I have created an interface IDiscover.
Now i came to 2 ways of allocating the memory as
IDiscoverPtr id(__uuid(TestClass)); and Test::IDiscover *id=NULL;
What is the differnce between these two....Any Information is appreciated..
First one is a Smart Pointer and the Second one is a normal pointer.
You don't need to worry about Releasing a Smart Pointer whereas you have to explicitly Release() a normal COM Interface Pointer.
For more details on Smart Pointers, Look Here
Apart from that, the first one will try to find a GUID from registry for your Class named TestClass and will try to create an Instance of this class through CoCreateInstance API Call. It will try to get the IDiscover interface pointer through the said CoCreateInstance call and will throw an error if it fails to do so. On successful execution of the line IDiscoverPtr id(__uuid(TestClass));, you should have a valid IDiscover interface pointer in id.
The Second one is simply declaration of an Interface pointer, nothing else. You will have to instantiate it yourself through (most of the times) CoCreateInstance or one of it's variants.
The first variant is a smart pointer, the second one is a raw (ordinary pointer). The smart pointer will call IUnknown::Release() of the connected object when it itselft goes out of scope. The raw pointer will not do so and you will possibly get a memory leak unless you call IUnknown::Release() of the conected object explicitly at a suitable moment.
The first variant will try to instantiate the COM object upon its own construction (since you use the constructor parameterised with the class id) and throw an exception if that can't be done. See sources for _com_ptr_t (comip.h) for details. The second variant will give you a pointer initialized to null - not connected to any object.
Smart pointers for COM objects have a set of member function useful for instantiating objects and calling QueryInterface() - this can often reduce the amount of code needed to write. With a raw pointer you will have to call CoCreateInstance() with a handful of parameters most of which you will set to default values and this will force you to write more code. Again see the comip.h for the full sources of _com_ptr_t - they are quite readable.
The general recommendation is to use smart pointers unless you have real reasons to do otherwise.

AddRef and function signature

I've always used the following rule for signatures of functions that return ref-counted objects based on whether they do an AddRef or not, but want to explain it to my colleagues too... So my question is, is the rule described below a widely followed rule? I'm looking for pointers to (for example) coding rules that advocate this style.
If the function does not add a reference to the object, it should be returned as the return value of the function:
class MyClass
{
protected:
IUnknown *getObj() { return m_obj; }
private:
IUnknown *m_obj;
};
However, if the function adds a reference to the object, then a pointer-to-pointer of the object is passed as a parameter to the function:
class MyClass
{
public:
void getObj(IUnknown **outObj) { *outObj = m_obj; (*outObj)->AddRef(); }
private:
IUnknown *m_obj;
};
It's much more typical to use the reference-counting smart pointers for cases when a new object is created and the caller has to take ownership of it.
I've used this same style on projects with a lot of COM. It was taught to me by a couple of people that learned it when they worked at NuMega on a little thing called SoftICE. I think this is also the style taught in the book "Essential COM", by Don Box (here it is at Amazon). At one point in time this book was considered the Bible for COM. I think the only reason this isn't still the case is that COM has become so much more than just COM.
All that said, I prefer CComPtr and other smart pointers.
One approach is to never use the function's return value. Only use output parameters, as in your second case. This is already a rule anyway in published COM interfaces.
Here's an "official" reference but, as is typical, it doesn't even mention your first case: http://support.microsoft.com/kb/104138
But inside a component, banning return values makes for ugly code. It is much nicer to have composability - i.e. putting functions together conveniently, passing the return value of one function directly as an argument to another.
Smart pointers allow you to do that. They are banned in public COM interfaces but then so are non-HRESULT return values. Consequently, your problem goes away. If you want to use a return value to pass back an interface pointer, do it via a smart pointer. And store members in smart pointers as well.
However, suppose for some reason you didn't want to use smart pointers (you're crazy, by the way!) then I can tell you that your reasoning is correct. Your function is acting as a "property getter", and in your first example it should not AddRef.
So your rule is correct (although there's a bug in your implementation which I'll come to in a second, as you may not have spotted it.)
This function wants an object:
void Foo(IUnknown *obj);
It doesn't need to affect obj's refcount at all, unless it wants to store it in a member variable. It certainly should NOT be the responsibility of Foo to call Release on obj before it returns! Imagine the mess that would create.
Now this function returns an object:
IUnknown *Bar();
And very often we like to compose functions, passing the output of one directly to another:
Foo(Bar());
This would not work if Bar had bumped up the refcount of whatever it returned. Who's going to Release it? So Bar does not call AddRef. This means that it is returning something that it stores and manages, i.e. it's effectively a property getter.
Also if the caller is using a smart pointer, p:
p = Bar();
Any sane smart pointer is going to AddRef when it is assigned an object. If Bar had also AddRef-ed well, we have again leaked one count. This is really just a special case of the same composability problem.
Output parameters (pointer-to-pointer) are different, because they aren't affected by the composability problem in the same way:
Again, smart pointers provide the most common case, using your second example:
myClass.getObj(&p);
The smart pointer isn't going to do any ref-counting here, so getObj has to do it.
Now we come to the bug. Suppose smart pointer p already points to something when you pass it to getObj...
The corrected version is:
void getObj(IUnknown **outObj)
{
if (*outObj != 0)
(*outObj)->Release();
*outObj = m_obj;
(*outObj)->AddRef(); // might want to check for 0 here also
}
In practise, people make that mistake so often that I find it simpler to make my smart pointer assert if operator& is called when it already has an object.