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());
}
/*
1. işaretçi: POINTER_INVALID
2. pointer.Value()=3.141592653589793
3. iş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());
}
/*
1. işaretçi: POINTER_INVALID
2. pointer.Value()=3.141592653589793
3. iş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