我已经习惯了C RAII设施,我希望在C/C++LI中以正确的方式使用RAII托管代码.
Herb
Sutter和
Microsoft都告诉我这是最好的做法.
我有这样的事情:
ref struct Managed { // No default constructor Managed( /*...*/ ) { /*...*/ } ~Managed() { /* Important non-managed resource release here */ } // ... }; ref struct UsesManaged { Managed^ m_; array<Managed^>^ a_; UsesManaged( Managed^ m,array<Managed^>^ a ) : m_(m),a_(a) {} // ... }; ref struct Creator { Managed^ m_; array<Managed^>^ a_; UsesManaged^ u_; Creator() { // Must allocate dynamically here,not in initializer list // because in my real code,I use "this" here for a callback. m_ = gcnew Managed( /*...*/ ); a_ = gcnew array<Managed^>( 2 ); a_[ 0 ] = gcnew Managed( /*...*/ ); a_[ 1 ] = gcnew Managed( /*...*/ ); u_ = gcnew UsesManaged( m_,a_ ); } };
我想(1)自动资源销毁,所以我不必手动删除每个gcnew’ed对象,特别是在异常情况下; (2)安全清晰地共享对象的能力(绕过std :: auto_ptr等不符合条件); (3)能够让我的类被VB或C#消耗,并在对象超出范围时自动运行清理(例如,由于异常).
在标准C中,我使用std :: shared_ptr和std :: vector或类似的工具来自动化RAII.在这里,我可以使用STL / CLI的向量,但没有shared_ptr等价物.我看到的唯一相关的C/C++LI智能指针是sparsely documented msclr::auto_handle,它类似于std :: auto_ptr,包括所有权转移语义,它与向量不兼容,尽管它们在数组中可以正常工作.
什么是实现我的三个目标的正确的C/C++LI方式? (另请注意,我的主要C/C++LI类,上面的Creator,将由VB / C#使用.)
解决方法
你可以使用托管代码获得RAII:如果你有这个:
ref class A { ~A() { // implements/overrides the IDisposable::Dispose method // free managed and unmanaged resources here } };
然后你可以这样做:
void foo() { A a(cons_args); // stack-like usage // use a ... }
这将被有效地视为:
void foo() { try { A^ a_ = gcnew A(cons_args); } finally { a_->~A(); } }