I have several unmanaged c++ classes that reference each other. In order to avoid dangling pointers when an instance is released, I’m using boost smart pointers, mostly shared_ptr. So far so good.
However I also have a wrapper in C++/CLI, in which almost every unmanaged class has its managed equivalent to expose it to .NET applications. The wrapper is quite simple, however I was forced to use an unsafe pointer to reference UnmanagedClass* from ManagedClass. I cannot use boost::shared_ptr as a member of ManagedClass, because the CLR does not support unmanaged types as class members (only pointers to them).
Example: class Car which contains 4 instances of class Wheel. Each of the 5 unmanaged instances have 5 managed equivalent instances. Unmanaged Car might need to change its wheels, it deletes 4 instances of unmanaged Wheel and creates 4 new ones. Managed Car asks for the new unmanaged Wheel to create 4 new managed instances of Wheel.
However, the 4 old managed instances of Wheel are still in scope in the managed world, and now contain a dangling pointer to the old unmanaged instances. Any ideas how to realize that the native equivalent of a wrapper was disposed? An easy task with smart pointers. Can I use them in managed code?
Why not use internal instance counting? Create a base native class:
Then use it as a base class for all of these and remember to call AddRef when you acquire an instance of class and Release() when you no longer need it (for example in destructor). You would have to do the same in you C++/CLI classes; implement a IDisposable interface and clean the held native class instances in the Dispose() method. It shouldn’t be much problematic to use, because you only would have to call AddRef once inside constructors and Release once inside destructors/Dispose.