Ich bin an die C++ RAII-Funktionen gewöhnt, und ich möchte RAII die richtige Weise mit verwaltetem Code in C++/CLI verwenden. HerbSutter und Microsoft beide sagen mir, das ist die beste Praxis.RAII in C++/CLI
Ich habe so etwas wie dies:
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_);
}
};
Ich möchte (1) automatische Ressourcenzerstörung, also muss ich nicht manuell jedes gcnew'ed Objekt löschen, insbesondere angesichts der Ausnahmen; (2) die Fähigkeit, Objekte sicher und klar zu teilen (die Weitergabe von std :: auto_ptr und dergleichen ist nicht zulässig); und (3) die Fähigkeit, dass meine Klasse von VB oder C# konsumiert wird und die Bereinigung automatisch ausgeführt wird, wenn das Objekt den Geltungsbereich verlässt (z. B. aufgrund einer Ausnahme).
In Standard-C++ würde ich std :: shared_ptr und std :: vector oder ähnliche Einrichtungen verwenden, um RAII zu automatisieren. Hier könnte ich den STL/CLI-Vektor verwenden, aber es gibt kein shared_ptr-Äquivalent. Der einzige relevante C++/CLI-Smart-Pointer, den ich sehe, ist der sparsely documented msclr::auto_handle, der std :: auto_ptr ähnelt, einschließlich der Semantik der Eigentumsübertragung, die nicht mit Vektoren kompatibel ist, obwohl sie in einem Array funktionieren würden.
Was ist der richtige C++/CLI-Weg, um meine drei Ziele zu erreichen? (Beachten Sie auch, dass meine Haupt-C++/CLI-Klasse, Creator im obigen, von VB/C# verbraucht wird.)
[Updates: Links zu Herb Sutter und MS an der Spitze hinzugefügt und Ziel 3 hinzugefügt (Verbrauch von VB/C#)]
Genau genommen ist dies nicht RAII, weil Sie Zuweisung, nicht Initialisierung verwenden, um die Ressource zu übernehmen. Es ist ein intelligenter Zeiger, der viel mit RAII teilt. –
Die IDisposable-Schnittstelle ist ein bewährtes Muster in verwaltetem Code. Aber Sie müssen * wirklich * auch einen Finalizer enthalten, damit die Ressource automatisch freigegeben wird. Hinzufügen! Verwaltet(). –
Hans, ich denke du hast deine längere Antwort vielleicht gelöscht. Es war hilfreich und ich wünschte, du hättest es verlassen, damit wir es dort diskutieren könnten. – metal