命名空间
namespace是一个特殊声明的区域,其中定义了各种ID:变量、函数、类等。其使用namespace关键字进行设置:
namespace name of_space {
//函数、类和变量定义的列表
}
|
应用'namespace'可以将全局的命名空间拆分为子空间。namespace中的所有ID都可以彼此使用,不需要特别指定。::操作符(语境解析操作)用于从外部访问命名空间(namespace)成员。
namespace ProjectData
{
class DataManager
{
public:
void LoadData() {}
};
void Func(DataManager& manager) {}
}
//+------------------------------------------------------------------+
//| 脚本程序起始函数 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 使用ProjectData命名空间
ProjectData::DataManager mgr;
mgr.LoadData();
ProjectData::Func(mgr);
}
|
命名空间(namespaces)用于以逻辑组的形式排列代码,并避免在程序中使用多个程序库时可能发生的名称冲突。在这种情况下,可以在其命名空间(namespaces)中声明每个程序库,以便显式访问每个程序库的必要函数和类。
命名空间(namespaces)可以在一个或多个文件中的多个块中声明。编译器在预处理期间将所有部分组合在一起,并且得到的命名空间包含所有部分中声明的所有成员。假设我们在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;}
}
|
全局命名空间(Global namespace)
如果ID没有在命名空间中显式声明,则认为它是全局命名空间的隐式部分。要显式地设置全局ID,请使用范围解析操作符,无需命名。这将可以使您将这个ID与位于不同命名空间中具有相同名称的任何其他元素区分开来。例如,导入函数时:
#import "lib.dll"
int Func();
#import
//+------------------------------------------------------------------+
//| 某个函数 |
//+------------------------------------------------------------------+
int Func()
{
return(0);
}
//+------------------------------------------------------------------+
//| 脚本程序起始函数 |
//+------------------------------------------------------------------+
void OnStart()
{
//+--- 调用导入函数
Print(lib::Func());
//+--- 调用我们的函数
Print(::Func());
}
|
在本例中,从DLL函数导入的所有函数都包含在相同名称的命名空间中。这使得编译器能够清楚地确定要调用的函数。
另见
全局变量、本地变量、可视范围和变量的生命周期、创建和删除对象