当我在 VS2008 中构建以下 C++/CLI 代码时,会显示代码分析警告 CA1001。
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;
};
警告:CA1001:Microsoft.Design:在“B”上实现 IDisposable,因为它创建了以下 IDisposable 类型的成员:“A”。
要解决此警告,我必须将此代码添加到 B 类:
~B() { delete m_a; }
但我不明白为什么。A 类通过其析构函数(和终结器)实现 IDisposable。
因此,当 A 被垃圾回收时,肯定会调用 A 的终结器或析构函数,从而释放其非托管资源。
为什么 B 必须添加一个析构函数才能在其 A 成员上调用“删除”?
如果 B 显式调用“删除 m_a”,GC 是否只会调用 A 的析构函数?
编辑:如果您使用声明 A 成员的“语法糖”方法,这似乎会自动工作,如下所示:
ref class B
{
public:
B() { }
protected:
A m_a;
};
但这并不总是可能的。
一旦没有其他人拥有指向它的指针,为什么 GC 不够聪明地自动处理 A^ 的托管引用指针?