Nesne İşaretçileri

MQL5'te karmaşık türde nesnelerin dinamik olarak oluşturulması mümkündür. Bu, oluşturulan nesnenin açıklayıcısını geri döndüren "new" operatörü kullanılarak yapılır. Açıklayıcı boyutu 8 bayttır. Sözdizimsel olarak, MQL5'teki nesne açıklayıcıları, C++'taki işaretçilere benzerdir.

Örnek:

MyObject* hobject= new MyObject();

C++'tan farklı olarak, yukarıdaki örnekteki "hobject" değişkeni belleğe olan bir işaretçi değildir, bir nesne açıklayıcısıdır. Ayrıca, MQL5'te fonksiyon parametrelerindeki tüm nesnelerin geçişi referans yoluyla yapılmalıdır. Aşağıda, fonksiyon parametrelerindeki nesnelerin referans yoluyla geçişlerine örnekler gösterilmektedir:

class Foo
  {
public:
   string            m_name;
   int               m_id;
   static int        s_counter;
   //--- yapıcılar ve yıkıcılar
                     Foo(void){Setup("noname");};
                     Foo(string name){Setup(name);};
                    ~Foo(void){};
   //--- Foo nesnesini başlat
   void              Setup(string name)
     {
      m_name=name;
      s_counter++;
      m_id=s_counter;
     }
  };
int Foo::s_counter=0;
//+------------------------------------------------------------------+
//| Komut dosyası başlatma fonksiyonu                                |
//+------------------------------------------------------------------+
void OnStart()
  {
//--- otomatik oluşturma ile nesneyi bir değişken olarak bildir
   Foo foo1;
//--- nesnenin geçişini referans yoluyla yap
   PrintObject(foo1);
 
//--- nesneye bir işaretçi bildir ve onu "new" operatörünü kullanarak oluştur
   Foo *foo2=new Foo("foo2");
//--- nesneye olan işaretçinin geçişini referans yoluyla yap
   PrintObject(foo2); // nesneye olan işaretçi, derleyici tarafından otomatik olarak dönüştürülür
 
//--- Foo nesneleri dizisi bildir
   Foo foo_objects[5];
//--- nesne dizisinin geçişini yap
   PrintObjectsArray(foo_objects); // nesne dizisinin geçişini yapmak için ayrı bir fonksiyon
 
//--- Foo türü nesnelere olan işaretçi dizisi bildir
   Foo *foo_pointers[5];
   for(int i=0;i<5;i++)
      foo_pointers[i]=new Foo("foo_pointer");
//--- işaretçi dizisinin geçişini yap
   PrintPointersArray(foo_pointers); // işaretçi dizisinin geçişini yapmak için ayrı bir fonksiyon
 
//--- sonlandırmadan önce, işaretçi olarak oluşturulan nesneleri sildiğinizden emin olun
   delete(foo2);
//--- işaretçi dizisini sil
   int size=ArraySize(foo_pointers);
   for(int i=0;i<5;i++)
      delete(foo_pointers[i]);
//---   
  }
//+------------------------------------------------------------------+
//|  Nesnelerin geçişi her zaman referansla yapılır                  |
//+------------------------------------------------------------------+
void PrintObject(Foo &object)
  {
   Print(__FUNCTION__,": ",object.m_id," nesne adı=",object.m_name);
  }
//+------------------------------------------------------------------+
//| Nesne dizisinin geçişini yap                                     |
//+------------------------------------------------------------------+
void PrintObjectsArray(Foo &objects[])
  {
   int size=ArraySize(objects);
   for(int i=0;i<size;i++)
      PrintObject(objects[i]);
  }
//+------------------------------------------------------------------+
//| İşaretçi dizisinin geçişini yap                                  |
//+------------------------------------------------------------------+
void PrintPointersArray(Foo* &objects[])
  {
   int size=ArraySize(objects);
   for(int i=0;i<size;i++)
      PrintObject(objects[i]);
  }
//+------------------------------------------------------------------+

 

Kullanmadan önce işaretçiyi kontrol edin

Geçersiz bir işaretçiye erişme girişimi, programın kritik olarak sonlandırılmasına neden olur. CheckPointer fonksiyonu, kullanmadan önce işaretçiyi kontrol etmek için kullanılır. İşaretçi aşağıdaki durumlarda geçersiz olabilir:

  • işaretçi NULL'a eşittir;
  • nesne, delete operatörü kullanılarak silinmiştir.

Sıfırdan farklı bir değer, verilere ilgili işaretçiden erişilebileceğini ifade eder.

class CMyObject
 {
protected:
  double             m_value;
public:
                     CMyObject(void);
                     CMyObject(double value) {m_value=value;};
                    ~CMyObject(void){};
  //---
  double             Value(void) {return(m_value);}
 };
//+------------------------------------------------------------------+
//| Komut dosyası başlatma fonksiyonu                                |
//+------------------------------------------------------------------+
void OnStart()
 {
//--- başlatılmamış bir nesne oluştur
  CMyObject *pointer;
  if(CheckPointer(pointer)==POINTER_INVALID)
    Print("1. işaretçi: ",EnumToString(CheckPointer(pointer)));
  else
    Print("1. pointer.Value()=",pointer.Value());
 
//--- işaretçiyi başlat
  pointer=new CMyObject(M_PI);
  if(CheckPointer(pointer)==POINTER_INVALID)
    Print("2. işaretçi: ",EnumToString(CheckPointer(pointer)));
  else
    Print("2. pointer.Value()=",pointer.Value());
 
//--- nesneyi sil
  delete(pointer);
  if(CheckPointer(pointer)==POINTER_INVALID)
    Print("3. işaretçi: ",EnumToString(CheckPointer(pointer)));
  else
    Print("3. pointer.Value()=",pointer.Value());
 }
/*
   1işaretçi: POINTER_INVALID
   2pointer.Value()=3.141592653589793
   3işaretçi: POINTER_INVALID
*/

İşaretçiyi hızlı bir şekilde doğrulamak adına, CheckPointer fonksiyonunun örtük çağrısı aracılığıyla işaretçinin geçerliliğini kontrol eden "!" (LNOT) operatörünü de kullanabilirsiniz. Bu, daha kısa ve net bir kod yazımı sağlar. Önceki örnekteki kontroller "!" operatörüyle bu kez şu şekilde görünür:

//+------------------------------------------------------------------+
//| Komut dosyası başlatma fonksiyonu                                |
//+------------------------------------------------------------------+
void OnStart()
 {
//--- başlatılmamış bir nesne oluştur
  CMyObject *pointer;
  if(!pointer)
    Print("1. işaretçi: ",EnumToString(CheckPointer(pointer)));
  else
    Print("1. pointer.Value()=",pointer.Value());
 
//--- işaretçiyi başlat
  pointer=new CMyObject(M_PI);
  if(!pointer)
    Print("2. işaretçi: ",EnumToString(CheckPointer(pointer)));
  else
    Print("2. pointer.Value()=",pointer.Value());
 
//--- nesneyi sil
  delete(pointer);
  if(!pointer)
    Print("3. işaretçi: ",EnumToString(CheckPointer(pointer)));
  else
    Print("3. pointer.Value()=",pointer.Value());
 }
/*
   1işaretçi: POINTER_INVALID
   2pointer.Value()=3.141592653589793
   3işaretçi: POINTER_INVALID
*/

"==" operatörü, NULL varlığının hızlı kontrolü için kullanılır. Örneğin: ptr==NULL veya ptr!=NULL.Ayrıca Bakınız

 

Değişkenler, Değişkenlerin Başlatılması, Değişkenlerin Görünürlük Alanları ve Ömürleri, Nesnelerin Yaratılması ve Silinmesi