Pragma Once in C++

Muhammad Husnain 11 Dezember 2023
Pragma Once in C++

Dieser Artikel beginnt mit einem Überblick über pragma once als Präprozessor-Direktive und einem einfachen Anwendungsbeispiel. Danach werden wir einige spezifische Eigenschaften von pragma once in Bezug auf seine Unterstützung in C und C++ behandeln, und zuletzt werden wir ein ganzheitlicheres Beispiel dafür aufnehmen, wie es verwendet werden kann und wie es besser ist als seine Alternativen.

Pragma Once in C++

pragma once wird in C und C++ als Präprozessordirektive verwendet. Präprozessordirektiven sind einzeilige Codeteile, die das Programm nicht ausmachen und stattdessen vom Präprozessor gelesen werden.

Der Präprozessor analysiert diese vor der Kompilierung des Codes. Der Präprozessor erwartet auch kein Semikolon am Ende dieser Direktiven.

Um die Direktive pragma once zu Ihrem Code hinzuzufügen, fügen Sie daher Folgendes am Anfang der Datei hinzu.

#pragma once

pragma once selbst ist kein Standard. Dies bedeutet, dass es von einigen Compilern nicht unterstützt wird und aufgrund seiner komplexen Implementierung möglicherweise nicht immer zuverlässig ist.

Es wird jedoch sehr häufig unterstützt; daher sollte die Verwendung von pragma once in den meisten Fällen kein Problem darstellen. Sein Zweck ist einfach: Es stellt sicher, dass die aktuelle Quelldatei (die Datei, in die die Direktive geschrieben wird) nur einmal in die Kompilierung aufgenommen wird.

Dieser Job kann alternativ auch mit include guards erledigt werden. Auf die Unterschiede gehen wir nach einem Anwendungsbeispiel von pragma once ein.

pragma once wird hauptsächlich beim Definieren von Klassen verwendet. Im folgenden Beispiel definieren wir zwei Klassen: Structure und Room.

Die Klasse Room erbt von der Klasse 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;
  }
};

Wir definieren nun die Klasse Room.

// Save this as Room.h
#pragma once

#include "Structure.h"

class Room {
  Structure example;

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

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

Wir können jetzt eine main-Funktion definieren, die die obigen Objekte verwendet.

// 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;
}

Wenn wir im obigen Beispiel den Code ausführen, erhalten wir als Ausgabe Name is: Example Name and id is: 1, was wir erwarten. Wenn wir das pragma once entfernen, erhalten wir jedoch die folgenden Fehler.

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
      |       ^~~~~~~~~

Die Klasse Structure ist zweimal definiert. Mit pragma once können wir dafür sorgen, dass es nur einmal gelesen wird.

Die Alternative besteht darin, stattdessen Bezeichner zu verwenden. Im Kontext des obigen Beispiels können wir es wie unten definiert tun.

#ifndef STRUCTURE
#define STRUCTURE

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

Im obigen Beispiel kann STRUCTURE beliebig ersetzt werden. Normalerweise behalten wir den Namen jedoch als etwas bei, das dem Namen der Klasse entspricht.

Allerdings gibt es hier mögliche Probleme. Erstens ist es ausführlicher, erfordert eine manuelle Entscheidungsfindung, und der Compiler hat keinen Schutz davor, dass der Programmierer den Makronamen versehentlich an anderer Stelle im Projekt verwendet.

Compiler sind in der Regel darauf optimiert, die Kompilierungsgeschwindigkeit pragma once zu erhöhen.

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