Namensraum

Ein Namespace (Namensraum) ist ein speziell deklarierter Bereich, in dem verschiedene IDs definiert sind: Variablen, Funktionen, Klassen, etc. Es wird über das Schlüsselwort namespase definiert:

namespace name of_space { 
  // Liste der Funktions-, Klassen- und Variablendefinitionen
}

Die Verwendung von 'namespace' ermöglicht die Aufteilung des globalen Namensraums in Unterräume. Alle IDs innerhalb des Namensraums stehen einander ohne zusätzliche Angabe zur Verfügung. Der Operator :: (Operator zur Auflösung des Geltungsbereiches) wird verwendet, um von außen auf Mitglieder eines Namensraums zuzugreifen.

namespace ProjectData
{
class DataManager
  {
public:
   void              LoadData() {}
  };
void Func(DataManagermanager) {}
}
//+------------------------------------------------------------------+
//| Skript Programm Start Funktion                                   |
//+------------------------------------------------------------------+
void OnStart()
  {
//--- mit dem Namensraum ProjectData arbeiten
   ProjectData::DataManager mgr;
   mgr.LoadData();
   ProjectData::Func(mgr);
  }

Namensräume werden verwendet, um einen Code in Form von logischen Gruppen anzuordnen und Namenskonflikte zu vermeiden, die bei der Verwendung mehrerer Bibliotheken in einem Programm auftreten könnten. In solchen Fällen kann jede Bibliothek in ihrem eigenen Namensraum deklariert werden, um explizit auf die notwendigen Funktionen und Klassen jeder Bibliothek zuzugreifen.

Ein Namensraum kann in mehreren Blöcken in einer oder mehreren Dateien deklariert werden. Der Compiler kombiniert alle Teile während einer Vorverarbeitung miteinander und der resultierende Namensraum enthält alle in allen Teilen deklarierten Elemente. Angenommen, wir haben eine Klasse in der Include-Datei Sample.mqh implementiert:

//+------------------------------------------------------------------+
//|                                                       Sample.mqh |
//+------------------------------------------------------------------+
class A
  {
public:
                     A() {Print(__FUNCTION__);}
  };

Wir wollen diese Klasse in unserem Projekt verwenden, aber wir haben bereits eine Klasse A. Um beide Klassen verwenden zu können und ID-Konflikte zu vermeiden, binden Sie die eingebundene Datei einfach in einen Namensraum ein:

//--- deklarieren der ersten Klasse A
class A
  {
public:
                     A() {Print(__FUNCTION__);}
  };
//--- die Klasse A aus der Datei Sample.mqh in den Namensraum von Library einfügen, um einen Konflikt zu vermeiden.
namespace Library
{
#include "Sample.mqh"
}
//--- und noch eine weitere Klasse zum Namensraum Library hinzufügen
namespace Library
{
class B
  {
public:
                     B() {Print(__FUNCTION__);}
  };
}
//+------------------------------------------------------------------+
//| Skript Programm Start Funktion                                   |
//+------------------------------------------------------------------+
void OnStart()
  {
//--- die Klasse A des globalen Namensraums verwenden
   A a1;
//--- die Klassen A und B aus dem Namensraum Library verwenden
   Library::A a2;
   Library::B b;
  }
//+------------------------------------------------------------------+
 
/*
Ergebnis:
   A::A
   Library::A::A
   Library::B::B
*/

Namensräume können verschachtelt werden. Ein verschachtelter Namensraum hat unbegrenzten Zugriff auf Mitglieder seines übergeordneten Bereichs, aber Mitglieder des übergeordneten Bereichs haben keinen unbegrenzten Zugriff auf den verschachtelten Namensraum.

namespace General
{
int Func();
 
namespace Details
{
 int Counter;
 int Refresh()  {return Func(); }
}
 
int GetBars()   {return(iBars(Symbol(), Period()));};
int Size(int i) {return Details::Counter;}
}

 

Globaler Namensraum

Wenn die ID nicht explizit im Namensraum deklariert wird, gilt sie als impliziter Teil des globalen Namensraums. Um die globale ID explizit festzulegen, verwenden Sie den Operator des Geltungsbereichs ohne Namen. Dadurch können Sie diese ID von jedem anderen Element mit dem gleichen Namen unterscheiden, das sich in einem anderen Namensraum befindet.  Zum Beispiel, wenn Sie eine Funktion importieren:

#import "lib.dll"
int Func();
#import
//+------------------------------------------------------------------+
//|  Some function                                              |
//+------------------------------------------------------------------+
int Func()
  {
   return(0);
  }
//+------------------------------------------------------------------+
//| Skript Programm Start Funktion                                   |
//+------------------------------------------------------------------+
void OnStart()
  {
//+--- Aufruf der importierten Funktion
   Print(lib::Func());
//+--- Aufruf unserer Funktion
   Print(::Func());
  }

In diesem Fall wurden alle aus der DLL-Funktion importierten Funktionen in den gleichnamigen Namensraum aufgenommen. Dadurch konnte der Compiler die aufzurufende Funktion eindeutig bestimmen.

Siehe auch

Global Variablen, Lokale Variablen, Sichtbereich und Lebensdauer der Variablen, Erzeugung und Entfernung der Objekte