MQL5 Derleyici, bir sınıf ile ona yönelik bir işaretçi arasında ayrım yapmaz

 

MT5 yapımı 1940

 //+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
class A
{
public :
     int iValue;
};
//......................
A m_A[ 2 ];

void OnStart ()
{
A a;

    m_A[ 0 ] =a; 
    m_A[ 1 ] = new A();
}
//+------------------------------------------------------------------+

Her iki durumda da derlenir:

A m_A[ 2 ]; // и так

A* m_A[ 2 ]; // и так

İlk durumda çıktı, çıkarılamayan bir nesnedir (yeni tarafından yaratılmıştır) ve bir bellek sızıntısıdır.

 1 undeleted objects left
1 object of type A left
24 bytes of leaked memory

Tamam, manuel olarak serbest bırakın .. ve sonra derleyici (aniden) dizinin işaretçi olmayanlar içerdiğini fark eder: " nesne işaretçisi bekleniyor"

 delete m_A[ 1 ]; // Если 'm_A' массив объектов -> object pointer expected

Tamam, bir dizi işaretçi olarak ilan ediyorum

A* m_A[ 2 ];

Derleniyor! Bu haberdi.. Peki, MQL'de işaretler var mı, yok mu? Gerçekten de, char , int vb. gibi yerleşik türlerle,

 '*' - pointer cannot be used

Ama şimdi yürütürken

m_A[ 0 ] =a; // получаем: "invalid pointer access"

Hangisi mantıklı.)

Sonuçlar soruları gündeme getiriyor:

1. Ana işlevlerini aynı C/C++'da işaretçiler olarak gerçekleştirmiyorlarsa, MQL'de neden bu eksik işaretçiler var?

2. MT en yakın bayta ne kadar bellek sızdığını biliyorsa ve bunu otomatik olarak serbest bırakabiliyorsa, bunlar neden silme ile flört ediyor?

 

Silerken , işaretçinin türünü kontrol etmeniz gerekir. Bir nesne yeni ile oluşturulur - silinmesi gerekir (örnekteki ikincisi) ve diğeri otomatiktir (örnekteki ilki), otomatik olarak silinir.

 
Dmitry Fedoseev :

Silerken , işaretçinin türünü kontrol etmeniz gerekir. Bir nesne yeni ile oluşturulur - silinmesi gerekir (örnekteki ikincisi) ve diğeri otomatiktir (örnekteki ilki), otomatik olarak silinir.

Onlar. ilk durumda, m_A[ 0 ], ' a' yığın nesnesinin bir kopyasını değil , işlevden çıktıktan sonra (başka bir işlevden bir çağrıysa) bu yerel nesneye yönelik bazı POINTER_AUTOMATIC türünde bir işaretçi içerecektir. POINTER_INVALID türü olur mu?

 
Daha sonra, genel durumda, sorun şuna benzer: derleyici, POINTER_AUTOMATIC türünde bir işaretçide, POINTER_DYNAMIC türünde bir işaretçi depolamaya izin verir ve bunun tersi de geçerlidir.
 
SemenTalonov :

Onlar. ilk durumda, m_A[ 0 ], ' a' yığın nesnesinin bir kopyasını değil , işlevden çıktıktan sonra (başka bir işlevden bir çağrıysa) bu yerel nesneye yönelik bazı POINTER_AUTOMATIC türünde bir işaretçi içerecektir. POINTER_INVALID türü olur mu?

Yanlış kullanılırsa her şey GEÇERSİZ hale gelebilir. Mesele POINTER_INVALID değil, otomatik olarak oluşturulan nesnenin de otomatik olarak silineceğidir.

Buradaki nesnenin kopyaları genel olarak hiçbir durumda çalışamaz. Bir işaretçi yalnızca bir işaretçidir - nesnenin nerede olduğunu gösteren bir sayıya sahip bir değişken, bu durumda "a" nesnesi. Yani, "a" nesnesine "a" veya "m_A[0]" aracılığıyla erişilebilir, bu iki farklı nesne değil, bir nesnedir.

İlke basittir - nesneyi yarattı - kendisi silin. Yaratmadı - tırmanmayın. Hiçbir yerde daha kolay.

 
SemenTalonov :
Daha sonra, genel durumda, sorun şuna benzer: derleyici, POINTER_AUTOMATIC türünde bir işaretçide, POINTER_DYNAMIC türünde bir işaretçi depolamaya izin verir ve bunun tersi de geçerlidir.

Tersine. POINTER_DYNAMIC türünde bir işaretçiye POINTER_AUTOMATIC türünde bir işaretçi atanabilir. Ancak bu hem doğru hem de iyi - birçok olasılığın kapılarını açıyor.

 

Anlamadığım bir şey mi var, sorun ne?

Bir dizi nesne alıyoruz ve ilk öğesini yığında oluşturulan nesneye eşitliyoruz. Aynı zamanda - kopyalama operatörünü bildirmeden! Bu zaten bir hata.

Nesnenin çok basit olduğu göz önüne alındığında - orada varsayılan bir kopya oluşturucu oluşturulur. Ve dizi , oluşturulan nesnenin bir kopyasını içerir .

Sorular - sorun değil.

1. İşaretçiler - rollerini oldukça yerine getirir. Şahsen, bir diziye yalnızca işaretçilerim yok.

2. MQL, seçmediğini kaldırmamalıdır. Doğru, Dmitry yukarıda söyledi - bir nesne yarattı - onu silin. Aynı C#'daki "çöp toplayıcı" uygulamasını gerçekten sevmiyorum, nesneler benim tarafımdan sağlandığında değil, toplayıcı istediği zaman silindiğinde.

 
Georgiy Merts :

Anlamadığım bir şey mi var, sorun ne?

Bir dizi nesne alıyoruz ve ilk öğesini yığında oluşturulan nesneye eşitliyoruz. Aynı zamanda - kopyalama operatörünü bildirmeden! Bu zaten bir hata.

Nesnenin çok basit olduğu göz önüne alındığında - orada varsayılan bir kopya oluşturucu oluşturulur. Ve dizi , oluşturulan nesnenin bir kopyasını içerir .

Bir kopya için beklediğim buydu.Varsayılan kopya oluşturucu bir hata değil.

Ancak Dmitry , bellekte yeni bir nesnenin ayrılacağını ve POINTER_AUTOMATIC türünde bir işaretçinin döndürüleceğini ve kopya olmayacağını iddia ediyor.

Herkes MQL'nin tuhaflıklarını kendi tarzında anlar)

 
SemenTalonov :

Bir kopya için beklediğim buydu.Varsayılan kopya oluşturucu bir hata değil.

Ancak Dmitry , bellekte yeni bir nesnenin ayrılacağını ve POINTER_AUTOMATIC türünde bir işaretçinin döndürüleceğini ve kopya olmayacağını iddia ediyor.

Herkes MQL'nin tuhaflıklarını kendi tarzında anlar)

Yani, bu nasıl "hata değil" ??? Tanımlanmamış bir operatör kullanıyorsunuz.

Orada neredeyse boş bir nesneniz olması iyi, ama ya bu nesnede başlatma gerektiren başka alt nesneler varsa ve bu nesnenin kendisi kaynaklar için bir istek gerektiriyorsa?

Bana göre, bildirilmeyen bir şeyi kullanamazsınız.

“Tuhaflıkları” görmedim, bence Dmitry, “nesnenin kopyası olmayacak” konusunda yanlış - ve bunun nedeni, bildirilmemiş bir operatörün kullanılmasıdır.

 

Nesnenin kopyası nereden gelecek? İşaretçinin bir kopyası - evet, ancak aynı nesneye işaret ediyor.

 
Georgiy Merts :

Yani, bu nasıl "hata değil" ??? Tanımlanmamış bir operatör kullanıyorsunuz.

Bunu ayrıca, açıkça bildirilmiş bir kopya oluşturucunun bu testte hiçbir şeyi değiştirmeyeceğini yazdım.

Apaçık olanı nasıl görmezsin.

bir nesne dizisinin bir öğesine bir işaretçi yerleştirilir ve bir işaretçi dizisinin bir öğesine bir nesne yerleştirilir.. bu gerçekten normal mi?

ilk durumda, nesnenin işaretçisi diziye gider; ikinci durumda, kopya oluşturucu çalışmalıdır, bu işlemler nasıl eşdeğer olabilir?

Neden: