Pointeurs d'Objets
MQL5 permet la création dynamique d'objets de type complexe. Ceci est fait en utilisant l'opérateur 'new'qui renvoie un descripteur de l'objet créé. La taille du descripteur est de 8 octets. Syntaxiquement, les descripteurs d'objets dans MQL5 sont similaires aux pointeurs C++.
Exemple :
MyObject* hobject= new MyObject();
|
Contrairement au C++, la variable "hobject" de l'exemple ci-dessus n'est pas un pointeur vers la mémoire, mais un descripteur d'objet. De plus, en MQL5, tous les objets en paramètres de fonction doivent être passés par référence. Les exemples ci-dessous montrent le passage d'objets en paramètres de fonction :
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){};
//--- initialise l'objet Foo
void Setup(string name)
{
m_name=name;
s_counter++;
m_id=s_counter;
}
};
int Foo::s_counter=0;
//+------------------------------------------------------------------+
//| Fonction de démarrage du programme |
//+------------------------------------------------------------------+
void OnStart()
{
//--- déclare l'objet comme une variable, avec la création automatique
Foo foo1;
//--- variante du passage d'un objet par référence
PrintObject(foo1);
//--- déclare un pointeur sur un objet et le crée avec l'opérateur 'new'
Foo *foo2=new Foo("foo2");
//--- variante de passage d'un pointeur vers un objet par référence
PrintObject(foo2); // le pointeur vers l'objet est automatiquement converti par le compilateur
//--- déclare un tableau d'objets Foo
Foo foo_objects[5];
//--- variante du passage d'un tableau d'objets
PrintObjectsArray(foo_objects); // une fonction séparée pour passer un tableau d'objets
//--- déclare un tableau de pointeurs vers des objets de type Foo
Foo *foo_pointers[5];
for(int i=0;i<5;i++)
foo_pointers[i]=new Foo("foo_pointer");
//--- variante du passage d'un tableau de pointeurs
PrintPointersArray(foo_pointers); // une fonction séparée pour passer un tableau de pointeurs
//--- avant de terminer, assurez-vous de supprimer les objets créés en tant que pointeurs
delete(foo2);
//--- supprime le tableau de pointeurs
int size=ArraySize(foo_pointers);
for(int i=0;i<5;i++)
delete(foo_pointers[i]);
//---
}
//+------------------------------------------------------------------+
//| Les objets sont toujours passés par référence |
//+------------------------------------------------------------------+
void PrintObject(Foo &object)
{
Print(__FUNCTION__,": ",object.m_id," Nom de l'objet=",object.m_name);
}
//+------------------------------------------------------------------+
//| Passe un tableau d'objets |
//+------------------------------------------------------------------+
void PrintObjectsArray(Foo &objects[])
{
int size=ArraySize(objects);
for(int i=0;i<size;i++)
PrintObject(objects[i]);
}
//+------------------------------------------------------------------+
//| Passe un tableau de pointeurs d'objets |
//+------------------------------------------------------------------+
void PrintPointersArray(Foo* &objects[])
{
int size=ArraySize(objects);
for(int i=0;i<size;i++)
PrintObject(objects[i]);
}
//+------------------------------------------------------------------+
|
Vérifie le pointeur avant utilisation
Une tentative d'accès à un pointeur invalide provoque l'arrêt critique du programme. La fonction CheckPointer est utilisée pour vérifier un pointeur avant utilisation. Le pointeur peut être invalide dans les cas suivants :
- le pointeur est égal à NULL ;
- l'objet a été détruit à l'aide de l'opérateur delete.
Cette fonction peut être utilisée pour valider un pointeur. Une valeur différente de zéro indique que les données sont accessibles au niveau de ce pointeur.
class CMyObject
{
protected:
double m_value;
public:
CMyObject(void);
CMyObject(double value) {m_value=value;};
~CMyObject(void){};
//---
double Value(void) {return(m_value);}
};
//+------------------------------------------------------------------+
//| Fonction de démarrage du programme |
//+------------------------------------------------------------------+
void OnStart()
{
//--- crée un objet non initialisé
CMyObject *pointer;
if(CheckPointer(pointer)==POINTER_INVALID)
Print("1. le pointeur est ", EnumToString(CheckPointer(pointer)));
else
Print("1. pointer.Value()=", pointer.Value());
//--- initialise le pointeur
pointer=new CMyObject(M_PI);
if(CheckPointer(pointer)==POINTER_INVALID)
Print("2. le pointeur est ", EnumToString(CheckPointer(pointer)));
else
Print("2. pointer.Value()=", pointer.Value());
//--- supprime l'objet
delete(pointer);
if(CheckPointer(pointer)==POINTER_INVALID)
Print("3. le pointeur est ", EnumToString(CheckPointer(pointer)));
else
Print("3. pointer.Value()=", pointer.Value());
}
/*
1. le pointeur est POINTER_INVALID
2. pointeur.Value()=3.141592653589793
3. le pointeur est POINTER_INVALID
*/
|
Pour valider rapidement le pointeur, vous pouvez également utiliser l'opérateur "!" (LNOT) qui le vérifie via un appel implicite à la fonction CheckPointer. Cela permet d'écrire du code plus concis et plus clair. Vous trouverez ci-dessous les vérifications de l'exemple précédent :
//+------------------------------------------------------------------+
//| Fonction de démarrage du programme |
//+------------------------------------------------------------------+
void OnStart()
{
//--- crée un objet non initialisé
CMyObject *pointer;
if(!pointer)
Print("1. le pointeur est ", EnumToString(CheckPointer(pointer)));
else
Print("1. pointer.Value()=", pointer.Value());
//--- initialise le pointeur
pointer=new CMyObject(M_PI);
if(!pointer)
Print("2. le pointeur est ", EnumToString(CheckPointer(pointer)));
else
Print("2. pointer.Value()=", pointer.Value());
//--- supprime l'objet
delete(pointer);
if(!pointer)
Print("3. le pointeur est ", EnumToString(CheckPointer(pointer)));
else
Print("3. pointer.Value()=", pointer.Value());
}
/*
1. le pointeur est POINTER_INVALID
2. pointeur.Value()=3.141592653589793
3. le pointeur est POINTER_INVALID
*/
|
L'opérateur "==" est utilisé pour une vérification rapide de NULL. Par exemple : ptr==NULL ou ptr!=NULL.
Voir aussi
Variables, Initialisation des Variables, Portée de Visibilité et Cycle de Vie des Variables, Créer et Supprimer des Objets