Hatalar, hatalar, sorular - sayfa 1183

 
Zeleniy :

Bir danışmanı test ederken hata veriyor

OrderSend işlevi için geçersiz kâr alma

Sipariş Gönderme hatası 4107

Danışman koduna girmeden nasıl düzeltebilirim?

ayarlarda kârı artırmayı veya azaltmayı deneyin
 
mql5 :
Bu nesne için ZeroMemory işlevini kullanamazsınız

Apaçık. Ama derleyici neden bu hatayı ZeroMemory'nin kullanıldığı yerde değil de sınıfın bildirildiği yerde gösteriyor? Kafa karıştırıcı. Hatanın ne olduğunu ve nerede olduğunu anlamaya çalışarak kafamı çoktan kırdım. Siz, lütfen, hatanın doğru yerde verildiğini belirtin. Sonuçta, örneğin, kopyalanmasına izin verilmeyen öğeler içeren bir nesneyi kopyalarken, hata tam olarak kopyalama sırasında ve sınıfın içinde bir yerde değil.

 
meat :

Bütün bunların pratik tarafına gidersek, o zaman zaten sorunla yüzleşmem gerekiyordu. Kod, statik nesneler kullandı. Sonra bazılarını dinamik olanlarla değiştirmeye karar verdim. Sonuç olarak, karşılaştırma ve atama işlemleri oldukça farklı çalışmaya başladı. Ve bu sorunu tespit etmek zordu, çünkü. program normal şekilde derlenmeye ve çalışmaya devam ediyor, ancak olması gerektiği gibi değil.

Sorunun özünü hemen anlamadım

 class B {};

class A {
public :
         bool operator !=( A* a ) { Print ( __FUNCTION__ ); return ( true   );  }
         bool operator !=( B* b ) { Print ( __FUNCTION__ ); return ( false );  }
         bool operator >>( A* a ) { Print ( __FUNCTION__ ); return ( true   );  }
         bool operator +( A* a )  { Print ( __FUNCTION__ ); return ( false   ); }
         bool operator !()        { Print ( __FUNCTION__ ); return ( true    ); }
};

void OnStart ()
{
        A *a = new A;
        B *b = new B;
         if ( a != a ) Print ( "1" );
         if ( a != b ) Print ( "2" );
         if ( a >> a ) Print ( "3" );
         if ( !a )     Print ( "4" );
         delete ( a );
         delete ( b );
}
Bu, (a != a) öğesinin bir işaretçi karşılaştırmasıyla sonuçlanırken (a >> a) öğesinin >>( A* ) operatörüne bir çağrıyla sonuçlandığını gösterir.

Bir çelişki var.

(a >> a) öğesinin davranışını diğer aşırı yüklenmiş operatörler gibi değiştiremezsiniz (== ve != hariç), çünkü bu, aşağıdaki yapıyı imkansız hale getirecektir, çünkü (A) döndürülemez, ancak yalnızca (A*) döndürülebilir. iade.

 class A {
public :
        A * operator >>( string str ) { return ( GetPointer ( this ) ); }
};

void OnStart ()
{
        A *a = new A;
        a << "1234" << "мы" << "всю ночь" << "тусили" ; //множественное применение оператора <<
}

İşaretçiyi nesneye (*a) aktarma işleminin olmaması nedeniyle aşırı yüklenmiş operatörleri tam olarak kullanmak da imkansız olacaktır.

Sadece davranışı değiştirmek için kalır (== ve !=)

İşaretçileri (== ve !=) birbirleriyle ve bir sayı \ sıfırla (işaretçilerle yapılan diğer işlemler anlamsız olduğundan) karşılaştırmak için (GetPointer) gibi özel bir işlev tanıtmanız veya derleyiciye açıkça yayınlamasını söylemeniz gerekir.

 void OnStart ()
{
        A *a = new A;
        B *b = new B;
         if ( ulong (a) != ulong (b) ) Print ( "2" ); //хочу сравнить указатели
         if (       a  !=       b  ) Print ( "2" ); //хочу вызвать operator != ( B* )

}

Böylece aşırı yüklenmiş operatörlerin tam olarak kullanılması olasılığı kalacak ve yukarıdaki çelişki ortadan kalkacaktır.

Genel kuralın tek makul istisnası, operatör=() olmalıdır, çünkü


class A {
public :
        A * operator =( A* a ) { return ( GetPointer ( this ) ); }
};
void OnStart ()
{
        A *a = new A;
        a = a; //не должно трактоваться компилятором как вызов operator=( A* ),
                // а должно остаться как присваивание указателю значения
}
 
Ve elbette, (*a)'yı en azından operatörler için kullanma önerisi, C++'da kabul edilen gösterime geri dönmektir.
 class A {
public :
         bool operator !=( A* a ) { Print ( __FUNCTION__ ); return ( true   );  }
};

void OnStart ()
{
        A *a = new A;
         if (  a !=  a ) Print ( 1 ); //сравнение указателей
         if ( *a != *a ) Print ( 2 ); //вызов operator !=( A* )
}

bir kerede tüm çelişkileri ortadan kaldıracaktır.

Kendimi düzelteceğim: aslında, böyle bir gösterim (*a) operatörlerin birden fazla uygulanması sorununu çözmediğinden (şimdi == ve != hariç tüm operatörlerle başarılı bir şekilde çalışır) çelişkiler yalnızca kısmen ortadan kalkar - bu nedenle, işaretçileri birbirleriyle karşılaştırmak için en iyi seçenek, eşitlik\eşitsizlik özel bir işlev kullanmaya devam etmektir - veya ulong yazmak için açık bir döküm

 
A100, mesajlar için teşekkürler, halledeceğiz.
 
Derleme Hatası
 class A {
public :
      A( int a1 ) : a3( a1 ) { }
  static int a2;
         int a3;
};
int A::a2 = 1 ;

void OnStart ()
{
         int b = A::a2;   //нормально
        A t1( b );     //нормально
        A t2( A::a2 ); //ошибка компиляции
        A* t3 = new A( A::a2 ); //нормально
}
if static üye oluşturucu argümanı (yeni dışında)
 
Derleyici, kaydırma işleminden sonra #define içinde yorum yapılmasına izin vermiyor
 #define f( x )                   \
        ( x != 0 &&   /*comment*/ \ 
          x != 1 )

peki tamam

 #define f( x )       \
        ( x != 0 &&  \ /*comment*/
          x != 1 )
Derleme Hatası
 

İşaretçiler konusuna devam edersek, standart ' & ' işaretçi alma operatörünü MQL'ye eklemek güzel olurdu, hantal GetPointer'dan çok daha kullanışlı ve kompakt olurdu. Ve yukarıda tartışıldığı gibi ulong kullanarak döküm yapmaya gerek yoktur. Böylece, cephanelikte * ve & operatörlerine sahip olarak, gerekli işlemleri benzersiz bir şekilde belirleyebiliriz:

 if (&a==&b) Print ( "Указатели равны" );
if (*a==*b) Print ( "Объекты равны" );


Ve bu ve işaretiyle ilgili bir şey daha var. MQL'de değişkenlere çok az referans vardır. Özellikle işaretçilerin sınırlı kullanımı göz önüne alındığında (yalnızca sınıf nesnelerine). Bir yapının veya çok boyutlu bir dizinin derinlemesine iç içe geçmiş bir öğesine erişmek genellikle gereklidir. Her seferinde tam yolu yazmanız gerekiyor, bu kodu çok karıştırıyor. Bir bağlantı oluşturarak her şeyi basitleştirebilirsiniz. Ve genel olarak, kolaylık sağlamak için bazı değişkenlerin adını yerel olarak "değiştirmek" gerekli olabilir. Ancak, burada açıkladığım şey. Bağlantı kullanmanın rahatlığı zaten herkes tarafından biliniyor. Ve şimdi bunun yerine #define kullanmanız gerekiyor, ki bu elbette çok kötü.

Eh, ayrıca bir işlevin sonucunu referans olarak iletme yeteneğine de ihtiyacınız var, yani. double & Func() { }

 

Son zamanlarda, Facebook'taki bloglardan yinelenen gönderiler oldu:

1

 
meat :

İşaretçiler konusuna devam edersek, standart ' & ' işaretçi alma operatörünü MQL'ye eklemek güzel olurdu, hantal GetPointer'dan çok daha kullanışlı ve kompakt olurdu. Ve yukarıda tartışıldığı gibi ulong kullanarak döküm yapmaya gerek yoktur. Böylece, cephanelikte * ve & operatörlerine sahip olarak, gerekli işlemleri benzersiz bir şekilde belirleyebiliriz:

Üye işlevlere yalnızca (*a) aracılığıyla erişimi kabul edersek, bu bariz avantajlar sağlamaz, aksine basit ve anlaşılır bir çoklu operatör uygulamasının imkansızlığına yol açar.

 class A {
public :
        A * operator >>( string str ) { Print ( __FUNCTION__ ); return ( GetPointer ( this ) ); }
};

void OnStart ()
{
        A *a = new A;
        a << "1234" << "мы" << "всю ночь" << "тусили" ; //простая и понятная запись

önerinize göre yeniden yazmayı deneyin

 void OnStart ()
{
        A *a = new A;
        *(*(*(*a << "1234" ) << "мы" ) << "всю ночь" ) << "тусили" ; //запутанная запись
}

Ve bir işaretçi yerine nesnenin kendisini kullanamazsınız, çünkü <<(...) operatörü bir nesneye yalnızca bir işaretçi döndürebilir.

İşaretçilerle hangi işlemler anlamsız değildir? - yalnızca kendi aralarında ve bir sayı ile karşılaştırma - bu nedenle, operatörlerin onsuz birden fazla kullanım olasılığını korumak için özel bir işleve (örneğin, bool ComparePointer(a, b)) verilerek ihmal edilmeleri gerekir. aşırı yüklenmenin kendisi ana anlamını kaybeder.