Let’s say you have the following unmanaged code:
StreamWriter’s destructor uses
m_pStream (perhaps by flushing the stream). This means that the order of destruction is important —
StreamWriter must be destroyed before its underlying
Now let’s try to write and use some simple managed C++ wrappers for these classes:
See the problem?
As I (gratituously) hinted above, we have a problem due to nondeterminstic destruction. Since the GC does not define the order in which it will destroy managed objects, we cannot guarantee that the
ManagedStreamWriter will be destroyed before the
ManagedStream. If the
ManagedStream is destroyed first, then its
Stream will be deleted before the
StreamWriter destructor is called. This means that
StreamWriter will be using a deleted pointer — a sure recipe for disaster.
I can think of a few possible solutions to this problem:
- Have the managed classes implement
IDisposable, and require developers to use it to achieve determinstic destruction. The main downside to this approach is “what if developers forget?”
- Recapture the interdependencies among unmanaged classes in the managed wrappers. For example, add a reference in
ManagedStreamobject. This will force the GC to properly order their destruction, and is probably the right way to go.