这样不是比在C#中的做更容易些吗?我恰好把StreamWriter声明移到了顶部并增加了一个额外的try块,就这些。甚至对于象在我的示例代码片断中的琐碎事情,如果所涉及的复杂性在C++中大大减少,那么,当你工作于更大的工程时你能想象使用栈语义对你的编码效率千万的影响。
还不确信?好,让我们看一下成员对象和它们的析构吧。Imagine CLI GC类R1和R2,二者都实现了Idisposable接口且都有函数F(),还有一个CLI GC类R,它有R1和R2成员和一个函数F()-它内部地调用R1和R2上的F()成员函数。让我们先看C#实现。
5) 一个disposable类继承层次的C#实现
class R1 : IDisposable{
public void Dispose() { }
public void F() { }
}
class R2 : IDisposable{
public void Dispose() { }
public void F() { }
}
class R : IDisposable{
R1 m_r1 = new R1();
R2 m_r2 = new R2();
public void Dispose()
{
m_r1.Dispose();
m_r2.Dispose();
}
public void F()
{
m_r1.F();
m_r2.F();
}
public static void CallR()
{
using(R r = new R())
{r.F();}
}
}
这里有几件事情要做:必须为每个disposable 类手工实现IDisposable接口,对于具有成员R1和R2的类R,Dispose方法也需要调用成员类上的Dispose。现在让我们分析上面几个类的C++实现。
6) 等价的C++实现
ref class R1
{
public:
~R1(){}
void F(){}
};
ref class R2
{
public:
~R2(){}
void F(){}
};
ref class R
{
R1 m_r1;
R2 m_r2;
public:
~R(){}
void F()
{
m_r1.F();
m_r2.F();
}
static void CallR()
{
R r;
r.F();
}
};
注意,这里不再有手工的Idisposable接口实现(我们的类中仅建立了析构器)而且最好的部分--类R的析构器(Dispose方法)并没有在该类可能含有的可释放的成员上调用Dispose-它没有必要这样做,编译器自动为之生成所有的代码!