目标指针
MQL5支持动态创建复杂类型对象。这是通过使用‘new’操作符来完成,该操作符返回已创建对象的描述符。描述符大小为8个字节。在语法上,MQL5中的对象描述符类似于C++指针。
例如:
MyObject* hobject= new MyObject();
|
与C++不同,上例中的‘hobject’变量不是指向内存的指针,而是对象描述符指针。此外,在MQL5中,函数参数中的所有对象都必须通过引用传递。下面的示例展示了对象作为函数参数的传递:
class Foo
{
public:
string m_name;
int m_id;
static int s_counter;
//--- 构造函数和析构函数
Foo(void){Setup("noname");};
Foo(string name){Setup(name);};
~Foo(void){};
//--- 初始化Foo对象
void Setup(string name)
{
m_name=name;
s_counter++;
m_id=s_counter;
}
};
int Foo::s_counter=0;
//+------------------------------------------------------------------+
//| 脚本程序起始函数 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 将对象声明为一个变量,并自动创建
Foo foo1;
//--- 通过引用传递对象的变体
PrintObject(foo1);
//--- 声明一个指向对象的指针,并使用'new'操作符进行创建
Foo *foo2=new Foo("foo2");
//--- 通过引用传递指对象指针的变体
PrintObject(foo2); // 对象指针由编译器自动转换
//--- 声明Foo对象的数组
Foo foo_objects[5];
//--- 传递对象数组的变体
PrintObjectsArray(foo_objects); // 用于传递对象数组的单独函数
//--- 声明指向Foo类型对象的指针数组
Foo *foo_pointers[5];
for(int i=0;i<5;i++)
foo_pointers[i]=new Foo("foo_pointer");
//--- 传递指针数组的变体
PrintPointersArray(foo_pointers); // 用于传递指针数组的单独函数
//--- 完成之前,一定要删除作为指针创建的对象
delete(foo2);
//--- 移除指针数组
int size=ArraySize(foo_pointers);
for(int i=0;i<5;i++)
delete(foo_pointers[i]);
//---
}
//+------------------------------------------------------------------+
//| 对象总是通过引用传递 |
//+------------------------------------------------------------------+
void PrintObject(Foo &object)
{
Print(__FUNCTION__,": ",object.m_id," Object name=",object.m_name);
}
//+------------------------------------------------------------------+
//| 传递对象数组 |
//+------------------------------------------------------------------+
void PrintObjectsArray(Foo &objects[])
{
int size=ArraySize(objects);
for(int i=0;i<size;i++)
PrintObject(objects[i]);
}
//+------------------------------------------------------------------+
//| 传递对象指针数组 |
//+------------------------------------------------------------------+
void PrintPointersArray(Foo* &objects[])
{
int size=ArraySize(objects);
for(int i=0;i<size;i++)
PrintObject(objects[i]);
}
//+------------------------------------------------------------------+
|
使用前检查指针
尝试访问无效指针会导致程序严重关闭。CheckPointer函数用于在使用前检查指针。指针在以下情况下可能无效:
此函数可用于验证指针。非零值表示可以在此指针处访问数据。
class CMyObject
{
protected:
double m_value;
public:
CMyObject(void);
CMyObject(double value) {m_value=value;};
~CMyObject(void){};
//---
double Value(void) {return(m_value);}
};
//+------------------------------------------------------------------+
//| 脚本程序起始函数 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 创建未初始化对象
CMyObject *pointer;
if(CheckPointer(pointer)==POINTER_INVALID)
Print("1. pointer is ", EnumToString(CheckPointer(pointer)));
else
Print("1. pointer.Value()=", pointer.Value());
//--- 初始化指针
pointer=new CMyObject(M_PI);
if(CheckPointer(pointer)==POINTER_INVALID)
Print("2. pointer is ", EnumToString(CheckPointer(pointer)));
else
Print("2. pointer.Value()=", pointer.Value());
//--- 删除对象
delete(pointer);
if(CheckPointer(pointer)==POINTER_INVALID)
Print("3. pointer is ", EnumToString(CheckPointer(pointer)));
else
Print("3. pointer.Value()=", pointer.Value());
}
/*
1. pointer is POINTER_INVALID
2. pointer.Value()=3.141592653589793
3. pointer is POINTER_INVALID
*/
|
要快速验证指针,您还可以使用操作符"!" (LNOT)通过隐式调用CheckPointer函数来检查。这允许更简洁和清晰的代码编写。以下是上一个示例中的检查:
//+------------------------------------------------------------------+
//| 脚本程序起始函数 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 创建未初始化对象
CMyObject *pointer;
if(!pointer)
Print("1. pointer is ", EnumToString(CheckPointer(pointer)));
else
Print("1. pointer.Value()=", pointer.Value());
//--- 初始化指针
pointer=new CMyObject(M_PI);
if(!pointer)
Print("2. pointer is ", EnumToString(CheckPointer(pointer)));
else
Print("2. pointer.Value()=", pointer.Value());
//--- 删除对象
delete(pointer);
if(!pointer)
Print("3. pointer is ", EnumToString(CheckPointer(pointer)));
else
Print("3. pointer.Value()=", pointer.Value());
}
/*
1. pointer is POINTER_INVALID
2. pointer.Value()=3.141592653589793
3. pointer is POINTER_INVALID
*/
|
Operator "==" is used for a quick check for NULL. 例如:ptr==NULL或ptr!=NULL。
另见
变量 , 初始变量 ,变量可见范围和使用期限 , 创建和删除目标