네임스페이스

네임스페이스는 변수, 함수, 클래스 등 다양한 ID가 정의되는 특별히 선언된 영역입니다. 이것은 namespace 키워드를 사용함으로써 설정됩니다:

namespace name of_space { 
  // 함수, 클래스 및 변수 정의 목록
 }

'namespace'를 적용하면 전역 네임스페이스를 하위 공간으로 분할할 수 있습니다. 네임스페이스 내의 모든 ID는 규격 없이 서로 사용할 수 있습니다. :: 연산자(컨텍스트 확인 작업)는 외부에서 네임스페이스 멤버에 액세스하는 데 사용됩니다.

namespace ProjectData
{
class DataManager
  {
public:
   void              LoadData() {}
  };
void Func(DataManagermanager) {}
 }
//+------------------------------------------------------------------+
//| 스크립트 프로그램 시작 함수                                         |
//+------------------------------------------------------------------+
void OnStart()
  {
//--- ProjectData 네임스페이스로 작업
   ProjectData::DataManager mgr;
   mgr.LoadData();
   ProjectData::Func(mgr);
  }

네임스페이스는 논리 그룹 형식으로 코드를 정렬하고 프로그램에서 여러 라이브러리를 사용할 때 발생할 수 있는 이름 충돌을 방지하는 데 사용됩니다. 이러한 경우 각 라이브러리의 네임스페이스에 선언하여 각 라이브러리의 필요한 함수 및 클래스에 명시적으로 액세스할 수 있습니다.

네임스페이스는 하나 이상의 파일에서 여러 블록으로 선언할 수 있습니다. 컴파일러는 사전 처리 중에 모든 부품을 함께 결합하며 결과 네임스페이스에는 모든 부품에 선언된 모든 멤버가 포함됩니다. Sample.mqh에 구현된 A 클래스가 파일을 포함한다고 가정합니다:

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

우리는 프로젝트에 이 클래스를 사용하고 싶지만, 이미 A 클래스가 있습니다. 클래스를 모두 사용하고 ID 충돌을 방지하려면 네임스페이스에 포함된 파일을 줄 바꿈하면 됩니다:

//--- 첫 A 클래스를 선언합니다
class A
  {
public:
                     A() {Print(__FUNCTION__);}
  };
//--- 충돌을 방지하기 위해 라이브러리 네임스페이스의 Sample.mqh 파일에서 A 클래스를 줄 바꿈
namespace Library
{
#include "Sample.mqh"
 }
//--- 라이브러리 네임스페이스에 다른 클래스 추가
namespace Library
{
class B
  {
public:
                     B() {Print(__FUNCTION__);}
  };
 }
//+------------------------------------------------------------------+
//| 스크립트 프로그램 시작 함수                                         |
//+------------------------------------------------------------------+
void OnStart()
  {
//--- 글로벌 네임스페이스에서 A 클래스 사용
   A a1;
//--- 라이브러리 네임스페이스의 A 및 B 클래스를 사용합니다.
   Library::A a2;
   Library::B b;
  }
//+------------------------------------------------------------------+
 
/*
결과:
   A::A
   Library::A::A
   Library::B::B
*/

네임스페이스는 내포할 수 있습니다. 중첩된 네임스페이스는 상위 공간의 멤버에 대한 무제한 액세스 권한을 가지지만 상위 공간의 멤버에게는 중첩된 네임스페이스에 대한 무제한 액세스 권한이 없습니다.

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

 

글로벌 네임스페이스

ID가 네임스페이스에 명시적으로 선언되지 않은 경우 글로벌 네임스페이스의 암시적 부분으로 간주됩니다. 글로벌 ID를 명시적으로 설정하려면 이름 없이 범위 지정 연산자를 사용하십시오. 이렇게 하면 이 ID를 다른 네임스페이스에 있는 동일한 이름의 다른 요소와 구별할 수 있습니다.  예를 들어 함수를 가져오는 경우:

#import "lib.dll"
int Func();
#import
//+------------------------------------------------------------------+
//|  일부 함수                                                        |
//+------------------------------------------------------------------+
int Func()
  {
   return(0);
  }
//+------------------------------------------------------------------+
//| 스크립트 프로그램 시작 함수                                         |
//+------------------------------------------------------------------+
void OnStart()
  {
//+--- 불러온 함수 호출
   Print(lib::Func());
//+--- 함수를 호출합니다
   Print(::Func());
  }

이 경우 DLL 함수에서 가져온 모든 함수가 동일한 이름의 네임스페이스에 포함됩니다. 이를 통해 컴파일러는 호출될 함수를 명확하게 결정할 수 있었습니다.

더 보기

글로벌 변수, 로컬 변수, 가시성 범위 및 변수의 수명, 오브젝트 생성 및 삭제