361 votes

Qu'entend-on par acquisition de ressources, c'est l'initialisation (RAII)?

Qu'entend-on par acquisition de ressources, c'est l'initialisation (RAII)?

445voto

the_mandrill Points 12530

C'est vraiment un nom terrible pour un incroyablement puissant concept, et peut-être le numéro 1 des choses que les développeurs C++ manquer quand ils passent à d'autres langues. Il y a eu un peu d'un mouvement pour essayer de renommer ce concept Portée Lié à la Gestion des Ressources, mais il ne semble pas avoir pris sur l'instant.

Quand nous disons "Ressource" on ne parle pas simplement de la mémoire - c'est peut-être descripteurs de fichiers, sockets réseau, base de données gère, les objets GDI... bref, des choses que nous avons fini de l'offre et donc, nous devons être en mesure de contrôler leur utilisation. Le "Champ-liée" signifie que la durée de vie de l'objet est liée à la portée d'une variable, de sorte que lorsque la variable est hors de portée alors que le destructeur sera la libération de la ressource. Une propriété intéressante de cette est qu'il fait plus exception à la sécurité. Par exemple, de comparer ce:

RawResourceHandle* handle=createNewResource();
handle->performInvalidOperation();  // Oops, throws exception
...
deleteResource(handle); // oh dear, never gets called so the resource leaks

Avec le RAII un

class ManagedResourceHandle {
public:
   ManagedResourceHandle(RawResourceHandle* rawHandle_) : rawHandle(rawHandle_) {};
   ~ManagedResourceHandle() {delete rawHandle_; }
   ... // omitted operator*, etc
};

ManagedResourceHandle handle(createNewResource());
handle->performInvalidOperation();

Dans ce dernier cas, lorsque l'exception est levée, et la pile est déroulée, les variables locales sont détruits, ce qui garantit que nos ressources est nettoyé et n'a pas de fuite.

131voto

Péter Török Points 72981

C'est un langage de programmation qui brièvement signifie que vous

  • encapsuler une ressource dans une classe dont le constructeur généralement - mais pas nécessairement** - acquiert la ressource, et de son destructeur toujours le libère)
  • l'utilisation de la ressource par l'intermédiaire d'une instance locale de la classe*
  • la ressource est automatiquement libérée lorsque l'objet devient hors de portée

Cela garantit que quoi qu'il arrive alors que la ressource est en cours d'utilisation, il finira par être libéré (que ce soit dû à un rendement normal, la destruction de l'objet contenant, ou une exception).

Il est largement utilisé de la bonne pratique en C++, car en plus d'être un moyen sûr de traiter avec des ressources, il rend également votre code beaucoup plus propre que vous n'avez pas besoin de mélanger code de gestion d'erreur avec la fonctionnalité principale.

* Mise à jour: "local" peut signifier une variable locale ou un non variable membre d'une classe. Dans ce dernier cas, le membre de la variable est initialisée et détruit avec son propriétaire de l'objet.

** Update2: @sbi a souligné, la ressource - bien que souvent est attribué dans le constructeur peut également être attribué à l'extérieur et transmis en tant que paramètre.

54voto

sbi Points 100828

"RAII" signifie "l'Acquisition de Ressources est d'Initialisation" et est en fait un abus de langage, car ce n'est pas la ressource de l'acquisition (et l'initialisation d'un objet), il est concerné, mais de libérer la ressource (par le biais de la destruction d'un objet).
Mais RAII est le nom que nous avons eu et ça colle.

Au cœur de sa pensée, l'idiome des caractéristiques de l'encapsulation des ressources (morceaux de mémoire, les fichiers ouverts, débloqué mutex, ce que vous voulez) en local, automatique objets, et d'avoir le destructeur de l'objet en libérant les ressources lorsque l'objet est détruit à la fin de la portée, il appartient à:

{
  raii obj(acquire_resource());
  // ...
} // obj's dtor will call release_resource()

Bien sûr, les objets ne sont pas toujours locales, automatique des objets. Ils pourraient être des membres d'une classe, trop:

class something {
private:
  raii obj_;  // will live and die with instances of the class
  // ... 
};

Si de tels objets gestion de la mémoire, ils sont souvent appelés "pointeurs intelligents".

Il existe de nombreuses variantes de ce. Par exemple, dans la première des extraits de code, la question se pose de savoir ce qui se passerait si quelqu'un voulait exemplaire obj. La solution la plus simple serait de tout simplement interdire la copie. std::unique_ptr<>, un pointeur intelligent pour faire partie de la bibliothèque standard, tel que présenté par la prochaine norme C++, est-ce.
Un autre pointeur intelligent, std::shared_ptr fonctionnalités de "propriété partagée" de la ressource (un objet alloué dynamiquement) qu'il détient. C'est, il peut être librement copié et toutes les copies font référence au même objet. Le pointeur intelligent garde une trace de la façon dont de nombreuses copies se référer au même objet et de le supprimer lorsque le dernier est détruit.
Une troisième variante se caractérise par std::auto_ptr qui implémente un type de coup-sémantique: Un objet appartient à un seul pointeur, et la tentative de copie d'un objet résultat (par le biais de la syntaxe hackery) dans le transfert de la propriété de l'objet vers la cible de l'opération de copie.

15voto

Dennis Points 5020

Le livre Programmation en C++ avec des Modèles de Conception a Révélé décrit RAII que (et je paraphrase*):

  1. L'acquisition de toutes les ressources
  2. L'utilisation des ressources
  3. En libérant les ressources

    • Les ressources sont mises en œuvre comme les classes, et tous les pointeurs ont de la classe des wrappers autour d'eux (des pointeurs intelligents).

    • Les ressources sont acquises par l'évocation de leurs constructeurs et publié de manière implicite (dans l'ordre inverse de l'acquisition), par l'évocation de leurs destructeurs.

* Parce que je n'ai pas reçu la permission écrite de l'éditeur de citer le livre.

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