Gotcha: CComPtrBase assignment
Today what started out as a crash due to a pure virtual call turned into finding a gotcha in CComPtrBase<T>. Essentially the code in question boiled down to the following. Can you spot the problem?
void GetAStudent(CComPtrBase<T> &spStudent)
{
CComPtr<Student> spLocal;
// Do some operation to get a student
spLocal = spStudent;
}
The problem isn't apparent until you look at the definition for CComPtrBase<T>::operater =. See the problem? Basically CComPtrBase<T>::operator= isn't explicitly defined. This means that C++ will automatically implement memberwise assignment. The RHS of the operator= will be a "const CComPtrBase<T>&".
CComPtr<T> derives from CComPtrBase<T> therefore it satisfies this and a memberwise assignment will occur. We now have two smart pointers on the same value. However the second smart pointer, CComPtrBase<T>, did not perform an AddRef. So when both objects are destroyed there will be an extra Release and hopefully a crash.
The fix?
- Use CComPtr<T> or CComPtrEx<T> instead of CComPtrBase<T>
- Less Optimal: call AddRef() on spLocal.