Pragma once en C++

Muhammad Husnain 11 décembre 2023
Pragma once en C++

Cet article commence par un aperçu de pragma once en tant que directive de préprocesseur et un exemple simple de son utilisation. Après cela, nous couvrirons quelques propriétés spécifiques de pragma once concernant son support en C et C++, et enfin, nous inclurons un exemple plus holistique de la façon dont il peut être utilisé et comment il est meilleur que ses alternatives.

Pragma once en C++

pragma once est utilisé en C et C++ en tant que directive de préprocesseur. Les directives du préprocesseur sont des morceaux de code d’une seule ligne qui ne constituent pas le programme et sont plutôt lus par le préprocesseur.

Le préprocesseur les analyse avant la compilation du code. Le préprocesseur n’attend pas non plus de point-virgule à la fin de ces directives.

Par conséquent, pour ajouter la directive pragma once à votre code, ajoutez ce qui suit en haut du fichier.

#pragma once

pragma once lui-même n’est pas standard. Cela signifie que certains compilateurs ne le prendront pas en charge et, en raison de sa mise en œuvre complexe, il se peut qu’il ne soit pas toujours fiable.

Cependant, il est très couramment pris en charge ; donc dans la plupart des cas, utiliser pragma once ne devrait pas être un problème. Son but est simple : il garantit que le fichier source courant (le fichier dans lequel la directive est écrite) n’est inclus qu’une seule fois dans la compilation.

Ce travail peut être fait alternativement en utilisant include les gardes. Nous discuterons des différences après un exemple d’utilisation de pragma once.

pragma once est principalement utilisé lors de la définition de classes. Dans l’exemple suivant, nous allons définir deux classes : Structure et Room.

La classe Room héritera de la classe Structure.

// This contains the code for the Structure class
// Save this as Structure.h
#pragma once

#include <iostream>
#include <string>

using namespace std;

class Structure {
  string struc_name;
  int id;

 public:
  void setVals() {
    struc_name = "Example Name";
    id = 1;
  }

  void printVals() {
    cout << "Name is: " << struc_name << " and id is: " << id << endl;
  }
};

Nous allons maintenant définir la classe Room.

// Save this as Room.h
#pragma once

#include "Structure.h"

class Room {
  Structure example;

 public:
  void initRoom() { example.setVals(); }

  void getRoom() { example.printVals(); }
};

Nous pouvons maintenant définir une fonction main qui utilise les objets ci-dessus.

// save this in a main.cpp file
#include <iostream>

#include "Room.h"
#include "Structure.h"

using namespace std;

int main() {
  Room testRoom;

  testRoom.initRoom();
  testRoom.getRoom();

  return 0;
}

Dans l’exemple ci-dessus, si nous exécutons le code, nous obtenons Name is: Example Name and id is: 1 comme sortie, ce qui correspond à ce que nous attendons. Cependant, si nous supprimons le pragma once, nous obtenons les erreurs suivantes.

In file included from Room.h:3,
                 from main.cpp:2:
Structure.h:8:7: error: redefinition of 'class Structure'
    8 | class Structure
      |       ^~~~~~~~~
In file included from main.cpp:1:
Structure.h:8:7: note: previous definition of 'class Structure'
    8 | class Structure
      |       ^~~~~~~~~

La classe Structure est définie deux fois. En utilisant pragma once, on peut s’assurer qu’il n’est lu qu’une seule fois.

L’alternative est d’utiliser des identifiants à la place. Dans le cadre de l’exemple ci-dessus, nous pouvons le faire comme défini ci-dessous.

#ifndef STRUCTURE
#define STRUCTURE

class Structure {
  // Some sample code here
};
#endif

Dans l’exemple ci-dessus, STRUCTURE peut être remplacé par n’importe quoi. Cependant, nous gardons normalement le nom comme quelque chose qui correspond au nom de la classe.

Cependant, il y a des problèmes possibles ici. Premièrement, il est plus verbeux, nécessite une prise de décision manuelle et le compilateur n’a aucune protection contre le programmeur utilisant accidentellement le nom de la macro ailleurs dans le projet.

Les compilateurs sont généralement optimisés pour pragma once augmentant la vitesse de compilation.

Muhammad Husnain avatar Muhammad Husnain avatar

Husnain is a professional Software Engineer and a researcher who loves to learn, build, write, and teach. Having worked various jobs in the IT industry, he especially enjoys finding ways to express complex ideas in simple ways through his content. In his free time, Husnain unwinds by thinking about tech fiction to solve problems around him.

LinkedIn