Estoy acostumbrado a las instalaciones de C++ RAII, y quiero usar RAII de la manera correcta con el código administrado en C++/CLI. HerbSutter y Microsoft me dicen que esta es la mejor práctica.RAII en C++/CLI
tengo algo como esto:
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_);
}
};
quiero (1) la destrucción automática de recursos, así que no tengo que eliminar todos los objetos gcnew'ed manualmente, sobre todo en la cara de excepciones; (2) la capacidad de compartir objetos de forma segura y clara (pasar por std :: auto_ptr y similares no califica); y (3) la posibilidad de que mi clase sea consumida por VB o C# y haga que la limpieza se ejecute automáticamente cuando el objeto se salga del alcance (por ejemplo, debido a una excepción).
En C++ estándar usaría std :: shared_ptr y std :: vector o instalaciones similares para automatizar RAII. Aquí, podría usar el vector de STL/CLI, pero no existe el equivalente de shared_ptr. El único puntero inteligente C++/CLI relevante que veo es sparsely documented msclr::auto_handle, que es similar a std :: auto_ptr, incluida la semántica de transferencia de propiedad, que no son compatibles con vectores, aunque funcionarían correctamente en una matriz.
¿Cuál es la forma correcta de C++/CLI para alcanzar mis tres objetivos? (Nota también, mi clase principal de C++/CLI, Creador en el anterior, será consumida por VB/C#.)
[Actualizaciones: Se agregaron enlaces a Herb Sutter y MS en la parte superior y se agregó el objetivo 3 (consumo de VB)/C#)]
Estrictamente hablando, esto no es RAII porque está utilizando la asignación, no la inicialización, para tomar posesión del recurso. Es un puntero inteligente que comparte mucho con RAII. –
La interfaz IDisposable es un patrón bien establecido en el código administrado. Pero * realmente * también tiene que incluir un finalizador, por lo que la liberación del recurso se realiza automáticamente. Añadir! Administrado(). –
Hans, creo que es posible que haya eliminado su respuesta más larga al respecto. Fue útil, y desearía que lo hubieras dejado para poder discutirlo allí. – metal