33 votes

L'utilisation de ScopeGuard conduit-elle vraiment à un meilleur code?

Je suis tombé sur cet article écrit par Andrei Alexandrescu et Petru Marginean il y a plusieurs années, qui présente et discute d'une classe utilitaire appelé ScopeGuard pour l'écriture du code garanti sans exception. Je voudrais savoir si le codage avec ces objets conduit vraiment à mieux de code ou si elle dissimule erreur de manipulation, que peut-être le gardien de la fonction de rappel devrait être mieux présenté dans un bloc catch? Quelqu'un aurait-il une expérience d'utilisation de ces à la production effective de code?

63voto

Konrad Rudolph Points 231505

Il améliore certainement votre code. Votre provisoirement formulé de réclamation, qu'il est obscur et que le code serait le mérite d'un catch bloc est tout simplement pas vrai en C++ parce que RAII est un idiome. Ressources de manutention en C++ est fait par l'acquisition de ressources et de collecte des ordures se fait par implicite des appels de destructeur.

D'autre part, explicite catch blocs serait gonfler le code et introduire subtile des erreurs parce que le flux de code devient beaucoup plus complexe et les ressources de manipulation doit être fait de manière explicite.

RAII (et particulièrement ScopeGuards) n'est pas un obscur technique en C++, mais fermement établi les meilleures pratiques.

30voto

j_random_hacker Points 28473

Oui.

Si il y a un seul morceau de code C++ que je pourrais recommander à chaque programmeur C++ de passer 10 minutes à l'apprentissage, il est ScopeGuard (qui fait maintenant partie de l'librement disponible Loki bibliothèque).

J'ai décidé d'essayer à l'aide d'un (légèrement modifié) version de ScopeGuard pour un petit GUI Win32 programme je travaillais. Win32 comme vous le savez a beaucoup de différents types de ressources qui doivent être fermés de différentes façons (par exemple, le noyau poignées sont généralement fermés avec CloseHandle(), GDI BeginPaint() doit être couplé avec un EndPaint(), etc.) J'ai utilisé ScopeGuard avec toutes ces ressources, et aussi pour l'allocation de travail tampons avec new (par exemple, pour le jeu de caractères conversions/Unicode).

Ce qui m'a étonné comment beaucoup plus court que le programme a été. Fondamentalement, il est un gagnant-gagnant: votre code est plus court et plus robuste à la fois. Futures modifications du code ne peut pas de fuite rien. Ils ne peuvent tout simplement pas. C'est pas cool ça?

2voto

1800 INFORMATION Points 55907

Je l'utilise souvent pour protéger l'utilisation de la mémoire, des choses qui doivent être libérées et qui ont été renvoyées par le système d'exploitation. Par exemple:

 DATA_BLOB blobIn, blobOut;
blobIn.pbData=const_cast<BYTE*>(data);
blobIn.cbData=length;

CryptUnprotectData(&blobIn, NULL, NULL, NULL, NULL, CRYPTPROTECT_UI_FORBIDDEN, &blobOut);
Guard guardBlob=guardFn(::LocalFree, blobOut.pbData);
// do stuff with blobOut.pbData
 

1voto

Leon Timmermans Points 23230

Je n'ai pas utilisé ce modèle particulier, mais j'ai déjà utilisé quelque chose de similaire auparavant. Oui, cela conduit à un code plus clair par rapport à un code tout aussi robuste implémenté de différentes manières.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X