Hatalar, hatalar, sorular - sayfa 1206

 
stringo :

Her şey doğru. Kesin eşleşmelere öncelik verilir. Ve gerçekten doğru

Neden böyle bir birleşme gerekli? Yanlış tasarlanmış programların işlenmesinin birleştirilmesi

Aynı kodun C++ ve MQL ile aynı şekilde çalışması için birleştirme gereklidir. C++'da böyle bir sipariş bir nedenle (!) yapılır (aksi takdirde, bazı aşamalarda belirsizlikler ortaya çıkar). Başlangıçta, C++ derleyicisinin bir mantıksızlığı ve/veya bir hatası olduğunu düşündüm, ancak şimdi bu yaklaşımın nesnel sebepleri olduğuna inanmaya meyilliyim. MQL'de, X::g'nin tam bir eşleşmeye sahip olduğunu, ancak Y::g'nin hala - C++'da olduğu gibi çağrıldığını gösteren, önceki örnek https://www.mql5.com/en/forum ile çelişen bir örnek. / 1111/sayfa1223#comment_1074757

 class A {};
class B : public A {};
class C : public B {};
class X {
public :
         virtual int g( C* c1, C* c2 ) { return ( 1 ); } //полное совпадение здесь
         virtual int g( C* c,  B* b )  { return ( 2 ); }
};
class Y : public C { //здесь ошибся, должно быть public : X
public :
         virtual int g( A* a, B* b ) { return ( 3 ); }
};
void OnStart ()
{
        C* c = new C;
        Y* y = new Y;
         Print ( y.g( c, c ));
}

Sonuç: 3

C++'ın "mantıksız" ancak kesin bir düzeni olduğu, MQL'nin ise rastgele bir sıraya sahip olduğu ortaya çıktı - türlerin tam eşleşmesiyle, bir durumda temel sınıf, diğerinde türetilmiş olan

 
A100 :

Aynı kodun C++ ve MQL ile aynı şekilde çalışması için birleştirme gereklidir. C++'da böyle bir sipariş bir nedenle (!) Başlangıçta, C++ derleyicisinin bir mantıksızlığı ve/veya bir hatası olduğunu düşündüm, ancak şimdi bu yaklaşımın nesnel sebepleri olduğuna inanmaya meyilliyim. MQL'de, X::g'nin tam bir eşleşmeye sahip olduğunu, ancak Y::g'nin hala - C++'da olduğu gibi çağrıldığını gösteren, önceki örnekle çelişen bir örnek.

Sonuç: 3

C++'ın "mantıksız" ancak kesin bir düzeni olduğu, MQL'nin rastgele bir düzeni olduğu ortaya çıktı - bir durumda, türlerin tam eşleşmesiyle, temel sınıf, diğerinde türetilmiş sınıf olarak adlandırılır.

Hangi özel C++ uygulamasından bahsediyorsunuz? Bu uygulamanın C++ standardına nasıl uyduğu. C++ standardı, aşırı yüklenmiş işlevlerin seçilme sırası hakkında ne söylüyor?

Aslında, tanımladığınız işlevlerin aşırı yüklenmesi yanlış tasarımın bir sonucudur.

Kaynakları taşımak bir efsanedir. Sadece test programı farklı C++ ortamlarında aynı şekilde çalışır. Farklı ortamlarda, en azından bir şekilde, gerçek bir program (gerçek pratik değeri olan binlerce kod satırından bahsediyoruz) farklı şekilde çalışacaktır. Ve MQL'nin C++ ile birleşmesi, tohum fonunun israfı hakkında söylenecek bir şey yok...

 
A100 :

Aynı kodun C++ ve MQL ile aynı şekilde çalışması için birleştirme gereklidir. C++'da böyle bir sipariş bir nedenle (!) yapılır (aksi takdirde, bazı aşamalarda belirsizlikler ortaya çıkar). Başlangıçta, C++ derleyicisinin bir mantıksızlığı ve/veya bir hatası olduğunu düşündüm, ancak şimdi bu yaklaşımın nesnel sebepleri olduğuna inanmaya meyilliyim. MQL'de, X::g'nin tam bir eşleşmeye sahip olduğunu, ancak Y::g'nin hala - C++'da olduğu gibi çağrıldığını gösteren, önceki örnek https://www.mql5.com/ru/forum ile çelişen bir örnek. / 1111/sayfa1223#comment_1074757

Sonuç: 3

C++'ın "mantıksız" ancak kesin bir düzeni olduğu, MQL'nin ise rastgele bir sıraya sahip olduğu ortaya çıktı - türlerin tam eşleşmesiyle, bir durumda temel sınıf, diğerinde türetilmiş olan

Bu örnekte bir hata yapmışsınız gibi görünüyor, eğer Y sınıfı C'den değil X'ten miras alıyorsa, davranış önceki örneğe karşılık gelecektir.
 
stringo :

C++ standardı, aşırı yüklenmiş işlevlerin seçilme sırası hakkında ne söylüyor?

Stroustrup'tan alıntı: "C++, temel sınıftaki sanal işlev türleri ile türetilmiş bir sınıftaki geçersiz kılma işlevi arasında tam bir eşleşme gerektirir"

Şimdi sorunu anladım ve C++'ın doğruluğu hakkında sonuca vardım. Yukarıdaki her iki örnekte de, türetilmiş sınıfın g() öğesi, temel sınıfın g() öğesini gizler (değiştirmek yerine). Ve sanallık mekanizması yalnızca bir ikame olduğunda etkinleştirilir ve ikame, tam bir tür eşleşmesi gerektirir (dönüş hariç). Yalnızca döndürülen türün kesinliği belirli uygulamaya bağlı olabilir.

 
mql5 :
Bu örnekte bir hata yapmışsınız gibi görünüyor, eğer Y sınıfı C'den değil X'den miras alıyorsa, davranış önceki örneğe karşılık gelecektir.

Evet, burada bir hata yaptım, bu nedenle hem C++ hem de MQL'nin açık ama farklı ikame ve saklanma sıraları var. Lütfen ikame ve gizleme arasındaki farkla ilgili önceki gönderideki argümanlarıma bakın.

C++'ın gizlenirken uyarı vermesi, bu sıranın bilinçli olarak seçildiğini gösterir.

 class A {};
class B : public A {};

class X {
public :
         virtual int g( A* a )
         virtual int f( B* a )
};
class Y : public X {
public :
         virtual int g( A* a ) //подмена  X::g
         virtual int f( A* a ) //сокрытие X::f
};
 
A100 :

Evet, burada bir hata yaptım, bu nedenle hem C++ hem de MQL'nin açık ama farklı ikame ve saklanma sıraları var. Lütfen ikame ve gizleme arasındaki farkla ilgili önceki gönderideki argümanlarıma bakın.

C++'ın gizlenirken uyarı vermesi, bu sıranın bilinçli olarak seçildiğini gösterir.

MQL derleyicisi, bir yöntem (fonksiyon) ararken, üst öğeye geçişi, göründüğü gibi, örneğin MS'den C ++ olarak düşünmez.

Mesaj için teşekkürler, bunu tartışacağız.

 
mql5 :
MQL derleyicisi, bir yöntem (fonksiyon) ararken, üst öğeye geçişi, göründüğü gibi, örneğin MS'den C ++ olarak düşünmez.

Mesaj için teşekkürler, bunu tartışacağız.

Yalnızca MS'den değil - Borland C++ 5.5.1 kullandığımı unutmayın.

Stroustrup, aksi takdirde, " sınıf nesnesinin sonu" ile ilgili hoş olmayan sonuçların olabileceğini yazıyor.

 
A100 :

Stroustrup'tan alıntı: "C++, temel sınıftaki sanal işlev türleri ile türetilmiş bir sınıftaki geçersiz kılma işlevi arasında tam bir eşleşme gerektirir"

Şimdi sorunu anladım ve C++'ın doğruluğu hakkında sonuca vardım. Yukarıdaki her iki örnekte de, türetilmiş sınıfın g() öğesi, temel sınıfın g() öğesini gizler (değiştirmek yerine). Ve sanallık mekanizması yalnızca bir ikame olduğunda etkinleştirilir ve ikame, tam bir tür eşleşmesi gerektirir (dönüş hariç). Yalnızca döndürülen türün kesinliği belirli uygulamaya bağlı olabilir.

Bekleyin bekleyin. Farklı parametrelere sahip aşırı yükleme fonksiyonlarından bahsediyoruz.

Sanal fonksiyonlar ise her zaman aynı tipte parametrelere sahiptir. Sanal işlevler tartışmamızın dışında

 
A100 :

Yalnızca MS'den değil - Borland C++ 5.5.1 kullandığımı unutmayın.

Stroustrup, aksi takdirde, " sınıf nesnesinin sonu" ile ilgili hoş olmayan sonuçların olabileceğini yazıyor.

MQL derleyicisinin - "çift kenarlı kılıç" davranışını değiştirmeyeceğimizi tartışmıştık. Açıklamama izin ver.

Sorun, yalnızca bitmiş sınıflarda (çalışma programı) değişiklik yaparken geçerlidir.
Ebeveyn daha uygun bir işleve sahip olduktan sonra, program aniden çalışmayı durdurur, çünkü. alt yöntem yerine ebeveyn yöntemi çağrıldı.
Peki, MQL'nin davranışını değiştirirseniz, benzer bir durum ortaya çıkabilir - bir çocuğa ebeveyn işlevi yerine (parametre dökümü olmadan) yeni bir yöntem eklendiğinde, alt yöntem çağrılmaya başlar ve program durur parametre dökümü ile tekrar çalışıyor.

Böylece C++ ile uyumluluk dışında hiçbir sorun çözülmeyecek, ayrıca derleyicinin davranışındaki değişiklik mevcut MQL programlarını etkileyecektir.
 

Так как переменные типа структур и простых типов не имеют указателей, то применять к ним функцию GetPointer() запрещено.

Bir işaretçiyi işlev argümanı olarak iletmek de yasaktır ( hangisi ??? GetPointer veya herhangi biri? ) . Yukarıdaki durumların tümünde, derleyici bir hata bildirir .

Belgelerden alıntı.

 class A{
public :
   void operator = ( const A* from){
       if ( GetPointer ( this ) == GetPointer (from))      // а тут я передаю и все ок
         Alert ( 1 );                                  // резутат 1  из за того что передаю this
       else
         Alert ( 2 );
   }
};

class B : public A{
public :
   void operator = ( const B& from){  
       if ( GetPointer ( this ) == GetPointer (from))
         return ;
       operator =((A*)( GetPointer ( this )));
   }
};
  B b;
   B bb;                        // забыл написать создание объектов и вызов функции.
   b = bb;

Neden yemin etmiyorsun??? Uyarıları zaten anladım - onu işleve aktarmadığım için kendimi suçluyorum.