我已经习惯了 C++ RAII 工具,我想以正确的方式使用 RAII 和 C++/CLI 中的托管代码。 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++/CLI 智能指针是 sparsely documented msclr::auto_handle ,它类似于 std::auto_ptr,包括所有权转移语义,它们与向量不兼容,尽管它们可以在数组中正常工作。
实现我的三个目标的正确 C++/CLI 方法是什么? (还要注意,我的主要 C++/CLI 类,上面的 Creator,将被 VB/C# 使用。)
[更新:在顶部添加了 Herb Sutter 和 MS 的链接,并添加了目标 3(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();
}
}
关于c++-cli - C++/CLI 中的 RAII,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3685451/