When I build the following C++/CLI code in VS2008, a code analysis warning CA1001 is displayed.
ref class A
{
public:
A() { m_hwnd = new HWND; }
~A() { this->!A(); }
protected:
!A() { delete m_hwnd; }
HWND* m_hwnd;
};
ref class B
{
public:
B() { m_a = gcnew A(); }
protected:
A^ m_a;
};
warning: CA1001 : Microsoft.Design : Implement IDisposable on 'B' because it creates members of the following IDisposable types: 'A'.
To resolve this warning, I would have to add this code to class B:
~B() { delete m_a; }
But I don't understand why. Class A implements IDisposable via its destructor (and finalizer).
So surely whenever A gets garbage-collected, then A's finalizer or destructor will get called, freeing its unmanaged resources.
Why does B have to add a destructor to call 'delete' on its A member?
Will the GC only call A's destructor if B explicitly calls "delete m_a"?
Edit: it seems this works automatically if you use the "syntax sugar" method of declaring the A member, like this:
ref class B
{
public:
B() { }
protected:
A m_a;
};
but this is not always possible.
Why isn't the GC clever enough to automatically dispose of the managed reference pointer of A^, once no one else has a pointer to it?