Scope Guards in C 11
Einer der Hauptvorteile von C 11-Lambda-Ausdrücken liegt in ihrer Fähigkeit, das Konzept von RAII auszudrücken ( Ressourcenbeschaffung ist Initialisierung) auf prägnante und elegante Weise. Die traditionelle Implementierung von RAII basiert auf Destruktoren, um Ressourcen freizugeben. Mit Lambda-Ausdrücken ist es jedoch möglich, ein Objekt zu erstellen, das beim Verlassen seines Bereichs eine Bereinigungsfunktion ausführt, unabhängig davon, wie dieser Verlassen erfolgt. Dies wird als Scope Guard bezeichnet.
Einfache Scope Guard-Implementierung
Hier ist ein Beispiel für eine einfache Scope Guard-Implementierung in C 11:
<code class="c++">template< typename Lambda > class ScopeGuard { mutable bool committed; Lambda rollbackLambda; public: ScopeGuard( const Lambda& _l) : committed(false) , rollbackLambda(_l) {} template< typename AdquireLambda > ScopeGuard( const AdquireLambda& _al , const Lambda& _l) : committed(false) , rollbackLambda(_l) { _al(); } ~ScopeGuard() { if (!committed) rollbackLambda(); } inline void commit() const { committed = true; } };</code>
Die ScopeGuard-Klasse verwendet einen Lambda-Ausdruck als Konstruktorargument, der die Bereinigungsaktion darstellt, die ausgeführt werden soll, wenn der Scope Guard den Gültigkeitsbereich verlässt. Das Committed-Flag zeigt an, ob die Bereinigungsaktion ausgeführt wurde.
Verwendung
Die ScopeGuard-Klasse kann verwendet werden, um sicherzustellen, dass Ressourcen ordnungsgemäß freigegeben werden, auch wenn eine Ausnahme auftritt . Beispielsweise erwirbt die folgende Funktion eine Ressource und stellt sicher, dass sie mithilfe eines Scope-Guards freigegeben wird:
<code class="c++">void SomeFuncThatShouldBehaveAtomicallyInCaseOfExceptions() { std::vector<int> myVec; std::vector<int> someOtherVec; myVec.push_back(5); //first constructor, adquire happens elsewhere const auto& a = RAII::makeScopeGuard( [&]() { myVec.pop_back(); } ); //sintactically neater, since everything happens in a single line const auto& b = RAII::makeScopeGuard( [&]() { someOtherVec.push_back(42); } , [&]() { someOtherVec.pop_back(); } ); b.commit(); a.commit(); }</code>
In diesem Beispiel wird der ScopeGuard verwendet, um sicherzustellen, dass die Elemente aus den Vektoren entfernt werden, auch wenn ein Es tritt eine Ausnahme auf.
Fazit
Scope Guards sind ein leistungsstarkes Tool, um sicherzustellen, dass Ressourcen in C ordnungsgemäß freigegeben werden 11. Die hier vorgestellte einfache Implementierung ist eine unkomplizierte Möglichkeit, dieses Muster zu implementieren. Es gibt jedoch komplexere Implementierungen, die zusätzliche Funktionen bieten, beispielsweise die Möglichkeit, den Besitz von Ressourcen zwischen Scope Guards zu übertragen.
Das obige ist der detaillierte Inhalt vonWie können C 11-Lambda-Ausdrücke zur Implementierung von Scope Guards verwendet werden?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!