Con trỏ đối tượng
MQL5 cho phép tạo động các đối tượng kiểu phức tạp. Điều này được thực hiện bằng cách sử dụng toán tử new
trả về một mô tả của đối tượng được tạo. Kích thước mô tả là 8 byte. Về mặt cú pháp, các mô tả đối tượng trong MQL5 tương tự như con trỏ trong C++.
Ví dụ:
MyObject* hobject = new MyObject();
Không giống như C++, biến hobject
trong ví dụ trên không phải là con trỏ tới bộ nhớ, mà là một mô tả đối tượng. Hơn nữa, trong MQL5, tất cả các đối tượng trong tham số hàm phải được truyền bằng tham chiếu. Các ví dụ dưới đây cho thấy việc truyền đối tượng làm tham số hàm:
class Foo
{
public:
string m_name;
int m_id;
static int s_counter;
//--- constructors and destructors
Foo(void){Setup("noname");};
Foo(string name){Setup(name);};
~Foo(void){};
//--- initialize the Foo object
void Setup(string name)
{
m_name=name;
s_counter++;
m_id=s_counter;
}
};
int Foo::s_counter=0;
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- declare the object as a variable, with automatic creation
Foo foo1;
//--- variant of passing an object by reference
PrintObject(foo1);
//--- declare a pointer to an object and create it using the 'new' operator
Foo *foo2=new Foo("foo2");
//--- variant of passing a pointer to an object by reference
PrintObject(foo2); // the pointer to the object is converted by the compiler automatically
//--- declare an array of Foo objects
Foo foo_objects[5];
//--- variant of passing an array of objects
PrintObjectsArray(foo_objects); // a separate function for passing an array of objects
//--- declare an array of pointers to objects of type Foo
Foo *foo_pointers[5];
for(int i=0;i<5;i++)
foo_pointers[i]=new Foo("foo_pointer");
//--- variant of passing an array of pointers
PrintPointersArray(foo_pointers); // a separate function for passing an array of pointers
//--- before finishing, be sure to delete the objects created as pointers
delete(foo2);
//--- remove the array of pointers
int size=ArraySize(foo_pointers);
for(int i=0;i<5;i++)
delete(foo_pointers[i]);
//---
}
//+------------------------------------------------------------------+
//| Objects are always passed by reference |
//+------------------------------------------------------------------+
void PrintObject(Foo &object)
{
Print(__FUNCTION__,": ",object.m_id," Object name=",object.m_name);
}
//+------------------------------------------------------------------+
//| Pass an array of objects |
//+------------------------------------------------------------------+
void PrintObjectsArray(Foo &objects[])
{
int size=ArraySize(objects);
for(int i=0;i<size;i++)
PrintObject(objects[i]);
}
//+------------------------------------------------------------------+
//| Pass an array of object pointers |
//+------------------------------------------------------------------+
void PrintPointersArray(Foo* &objects[])
{
int size=ArraySize(objects);
for(int i=0;i<size;i++)
PrintObject(objects[i]);
}
//+------------------------------------------------------------------+
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
Kiểm tra con trỏ trước khi sử dụng
Việc cố gắng truy cập một con trỏ không hợp lệ sẽ gây ra tắt chương trình nghiêm trọng. Hàm CheckPointer được sử dụng để kiểm tra con trỏ trước khi sử dụng. Con trỏ có thể không hợp lệ trong các trường hợp sau:
Hàm này có thể được dùng để xác thực con trỏ. Giá trị khác không cho thấy dữ liệu có thể được truy cập tại con trỏ này.
class CMyObject
{
protected:
double m_value;
public:
CMyObject(void);
CMyObject(double value) {m_value=value;};
~CMyObject(void){};
//---
double Value(void) {return(m_value);}
};
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- create a non-initialized object
CMyObject *pointer;
if(CheckPointer(pointer)==POINTER_INVALID)
Print("1. pointer is ", EnumToString(CheckPointer(pointer)));
else
Print("1. pointer.Value()=", pointer.Value());
//--- initialize the pointer
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 the object
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
*/
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
Để nhanh chóng xác thực con trỏ, bạn cũng có thể sử dụng toán tử "!" (LNOT) kiểm tra nó thông qua lời gọi ngầm định của hàm CheckPointer. Điều này cho phép viết mã ngắn gọn và rõ ràng hơn. Dưới đây là các kiểm tra từ ví dụ trước:
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- create a non-initialized object
CMyObject *pointer;
if(!pointer)
Print("1. pointer is ", EnumToString(CheckPointer(pointer)));
else
Print("1. pointer.Value()=", pointer.Value());
//--- initialize the pointer
pointer=new CMyObject(M_PI);
if(!pointer)
Print("2. pointer is ", EnumToString(CheckPointer(pointer)));
else
Print("2. pointer.Value()=", pointer.Value());
//--- delete the object
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
*/
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
Toán tử "==" được sử dụng để kiểm tra nhanh NULL. Ví dụ: ptr==NULL
hoặc ptr!=NULL
.
Xem thêm
Biến, Khởi tạo biến, Phạm vi hiển thị và tuổi thọ của biến, Tạo và xóa đối tượng