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

 
= işareti, bir nesnenin bellek alanını başka bir nesnenin bellek alanına kopyalar. Tüm nesneler oldukları yerde kalır.
 
Vladimir Simakov :
Onu yine de aramayın. Saf bellek sızıntısı.

arayabileceğinizden emin olun.

 

Bu arada, beyler, geliştiriciler, burada düzeltmek hala daha iyi. Ne de olsa, new gerçekten bir işaretçi döndürür, bu nedenle diğer uçta = aynı zamanda bir işaretçi olduğunu bir kontrol edin, örtük dökümü kaldırın (A) new A(); burada, anladığım kadarıyla - tam olarak olan budur.

 
Vladimir Simakov :

Bu arada, beyler, geliştiriciler, burada düzeltmek hala daha iyi. Ne de olsa, new gerçekten bir işaretçi döndürür, bu nedenle diğer uçta = aynı zamanda bir işaretçi olduğunu bir kontrol edin, örtük dökümü kaldırın (A) new A(); burada, anladığım kadarıyla - tam olarak olan budur.

Bu operatöre bir çağrı gider

Ticaret, otomatik ticaret sistemleri ve ticaret stratejilerinin test edilmesi hakkında forum

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

fxsaber , 2019.01.10 06:36

Ne zamandan beri tanımlanmışlar (geliştiricilere soru)

 void A:: operator =( const A& );
void A:: operator =( const A* );

ve nasıl çalışırlar? Aşağıdaki derlenmiş kod çılgın görünüyor

    A* b = NULL ;    
    m_A[ 1 ] = b;    


Kabaca böyle görünüyor

 class A
{
public :
     int iValue;
    
     void operator =( const A* Ptr )
    {
       Print ( __FUNCSIG__ );
      
       this .iValue = Ptr.iValue;
    }
};
//......................
A m_A[ 2 ];

void OnStart ()
{
A a;

    m_A[ 0 ] =a; 
    m_A[ 1 ] = new A();
}
 
fxsaber :

Bu operatöre bir çağrı gider


Kabaca böyle görünüyor

Evet anladım. İyi böyle bir tırmık çıktı. Bu arada, C++'da = operatörünün böyle bir aşırı yükü yoktur, VS yemin eder.
 

Garip konu ama. Yaygara yapmadan önce, MQL'de işaretçilerin tüm yaşamları boyunca dolaylı olarak nesnelere (referanslı) olarak kullanıldığını bilmek güzel olurdu, bu uygundur ve herkes buna alışmıştır. Okunması zor girişler a()->b()->c()->d() yerine, normal OOP formatında yazabilirsiniz: a().b().c().d( ) ve işlevlere geçiş sürecinde daha az gereksiz dönüşüm yapın. Ve şimdi birinin her şeyi değiştirmekten hoşnutsuzluğu yüzünden mi?

 
Alexey Navoykov :

Garip konu ama. Yaygara yapmadan önce, MQL'de işaretçilerin tüm yaşamları boyunca dolaylı olarak nesnelere (referanslı) olarak kullanıldığını bilmek güzel olurdu, bu uygundur ve herkes buna alışmıştır. Okunması zor girişler a()->b()->c()->d() yerine, normal OOP formatında yazabilirsiniz: a().b().c().d( ) ve işlevlere geçiş sürecinde daha az gereksiz dönüşüm yapın. Ve şimdi birinin her şeyi değiştirmekten hoşnutsuzluğu yüzünden mi?

Bu dökümle ilgili değil. İçeri girmedin.

 

MQL - C++'ın beyan edilen prototipine odaklanırsak.

C++ 'da, m_A bir nesneler dizisiyse, yeni operatör sırasıyla bir işaretçi döndürür:

m_A[ 1 ] = new A();

burada bir tür hatası olacaktır.

Bu satır derleyici tarafından atlanır:

m_A[ 1 ] = *( new A() );

Ancak bu bir bellek sızıntısına neden olur.


MQL'nin de aynı davranışa sahip olması güzel olurdu.

 
Alexey Navoykov :

Garip konu ama. Yaygara yapmadan önce, MQL'de işaretçilerin tüm yaşamları boyunca dolaylı olarak nesnelere (referanslı) olarak kullanıldığını bilmek güzel olurdu, bu uygundur ve herkes buna alışmıştır. Okunması zor girişler a()->b()->c()->d() yerine, normal OOP formatında yazabilirsiniz: a().b().c().d( ) ve işlevlere geçiş sürecinde daha az gereksiz dönüşüm yapın. Ve şimdi birinin her şeyi değiştirmekten hoşlanmaması yüzünden mi?

Ve basit örneklerde ayrıntılı olarak.

A a;

// 'a' ожидает объект
 
a = new A(); // а ему дают указатель, ведь можно же

// что в MQL равнозначно?
a = *(A*) new A();

Sonuç olarak elimizde

1. 'a' , oluşturulan nesnenin bir kopyasını alır, yeni oluşturulan nesnenin işaretçisi kaybolur

2. new nesne oluşturmada/bellek ayırmada başarısız olursa 'a'ya ne olacak?

İkinci durum (tersi)

A* a; // глобальный указатель - 'a' ожидает указатель на объект

// далее всё происходит внутри некой функции
A b; // создаем второй в стеке (ну типа в стеке, не суть)

a =b;
// т.е. тут объект "неявно кастится" к указателю?)
a = &b;

1. fonksiyondan çıktıktan sonra, yerel bir nesne olarak 'b' yok edilmelidir.

o zaman 'a' ne anlama gelir?

2. Yoksa kopyalama operatörü çalışmaya devam edecek ve 'b', 'a' işaretçisine kopyalanacak mı? ve 'a' önceden tanımlanmamışsa?

 
SemenTalonov :

İkinci durum (tersi)

A* a; // глобальный указатель - 'a' ожидает указатель на объект

// далее всё происходит внутри некой функции
A b; // создаем второй в стеке (ну типа в стеке, не суть)

a =b;
// т.е. тут объект "неявно кастится" к указателю?)


Burada, tam tersine, a işaretçisi dolaylı olarak nesneye atılır (başvurusu kaldırılır) ve ardından ona = operatörü uygulanır. Dün fxsaber bundan da bahsetti.

Ve bu durumda, bu tür davranışları yasaklamanın daha iyi olduğuna katılıyorum. Mantıksal olarak MQL kurallarıyla çelişmese de (çünkü = operatörünü çağırmak başka herhangi bir nesne yöntemini çağırmaya eşdeğerdir), bu tür kodun belirsiz algılanmasına ve ince hatalara yol açar. Ve bu sadece = operatörü için değil, aynı zamanda en azından == ve != için de geçerlidir. Ve belki de diğer operatörler için bu tür dökümleri yasaklamak gerekir. Çünkü C++'da operatörlere başvurabilirsiniz: +-<>[].

Kısacası, karar şudur: C++'da işaretçiler için izin verilen bir işaretçiye operatörler uygularken, bu işaretçinin bir nesneye örtük olarak yayınlanmasını yasaklayın. Buna göre yukarıdaki örnekte bir derleme hatası olacaktır.