Şablon parametreli derleyici hatası = void* - sayfa 6

 
Alexey Navoykov :

Evet, her şey yolunda gidiyor, ne icat ediyorsunuz:

Günlükte şunları elde ederiz:

geçersiz A::~A()
geçersiz B::~B()

Ve neden buna düştüm...

O zaman özür dilerim, bunun mümkün olduğunu bilmiyordum, MKL çok fazla C ++ değil. Artı tarafta, boşluğu* kaldırmak UB'dir.

 

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

MetaTrader 5 platformunun yeni versiyonu 1930 yapımı: MQL5'te kayan grafik pencereleri ve .Net kitaplıkları

Alexey Navoykov , 2018.12.15 02:44

Sevgili geliştiriciler. Daha önce dallardan birinde, bir temel sınıfın türetilmiş bir sınıfa örtük olarak dönüştürülmesine izin veren bir derleyici kusuru tartışıldı, ancak görünüşe göre bu sizin tarafınızdan fark edilmedi. Bu, hataları kontrol etmeyi zorlaştıran ve OOP'nin aktif kullanımı ile sürekli bir baş ağrısı haline gelen ciddi bir problemdir. Bu tür bir döküm yalnızca açık olmalıdır. Bu hem C++ hem de C# için genel bir kuraldır.

 class A {  };

class B : public A { };

A* a = new A;

B* b = a;   // Нет ошибки компиляции!

void f(B*) {  }

void OnInit ()
{ 
  f(a);   // Нет ошибки компиляции!
}  

Buraya ne dersin?

 class A {  };

class B : public A { };

A* a = new A;

void * v = a;

B* b = v;   // Нет ошибки компиляции!


Bu davranış da bir hata olarak kabul edilmeli mi?

 
Alexey Navoykov :

Stilist kodu okunabilir koddan okumayı zorlaştırıyorsa, belki böyle bir stilist onun için çalışmıyor?

Bana gelince, bir şekillendirici ancak TÜM kuralları esnek bir şekilde özelleştirilebildiğinde iyidir.

Peki, bir başkasının kodunu basılı bir biçimde (veya burada olduğu gibi bir forumda) okursanız.

 
fxsaber :
ek hakkında parantez
((A*)(b.GetPtr())).f(); // Доп. скобки, чтобы подчеркнуть, что именно имелось в виду, не полагаясь на приоритеты.

Evet, seni vurgulayabilir, ama benim için tam tersine, sadece kafa karıştıracak. Ve bu ifadeye hemen bakıyorum, burada kimin yönteminin çağrıldığını anlayamıyorum. Ve önceki iki satırda - her şey bir anda açık.

Tam olarak ne yapıldığını anlamak için tüm parantezleri açmanız gerekir. Daha fazla parantez - neler olduğunu anlamak için daha fazla zaman harcanır. Özellikle herhangi bir şekilde boşluklarla ayrılmamışlarsa.

 
Alexey Navoykov :

Evet, seni vurgulayabilir, ama benim için tam tersine, sadece kafa karıştıracak. Ve bu ifadeye hemen bakıyorum, burada kimin yönteminin çağrıldığını anlayamıyorum. Ve önceki iki satırda - her şey bir anda açık.

Tam olarak ne yapıldığını anlamak için tüm parantezleri açmanız gerekir. Daha fazla parantez - neler olduğunu anlamak için daha fazla zaman harcanır. Özellikle herhangi bir şekilde boşluklarla ayrılmamışlarsa.

Burada ekstra. köşeli ayraçlar okunamaz - bırak boşlukları aralayarak şekillendirici bunu yapsın.

Ve yazarken kendini kontrol etmek için. Hassas bir yerde yazarken, diğer dillere taşınabilen çapraz platform kodu yazdığımı (ve yalnızca MT4 / 5 olması gerekmez) fark ederken neden başka birinin önceliklerine güveneyim? Ekle. parantezler, dil önceliklerinin etkisini tamamen ortadan kaldırdı. Her şey kesinlikle netleşir. Bu sayede, bir sonraki yapıdan sonra bu yerde hiçbir şeyin kırılmayacağı% 100 güvenilirlik ortaya çıkıyor.


Üstelik bu parantez içine alınmış cehennemi okuduğumda, burada tam olarak ne demek istediğimi kesinlikle anlamak için zaman ayırmaya zorlanacağım. Ve görünürlük hakkında

 bool a = ( 1 < 2 ) && ( 3 < 4 );
bool b = 1 < 2 && 3 < 4 ;

Hangisi daha iyi diye soralım.

 
fxsaber :

Bu davranış da bir hata olarak kabul edilmeli mi?

Kesinlikle. Bu aynısı.

Böylece, bir problemin gerçekten mümkün olduğu ve en azından uyarılara ihtiyaç duyulduğu (ve genel olarak bir derleme hatası ) olduğu ortaya çıktı, o zaman hiçbir şey verilmez. Ancak parantezlerin dayatılmasıyla uyarıları boşa çıkarmazlar) Ve burada bazıları parantez olmadan derlemeyi yasaklamayı ve hatta kelepçelerle tehdit etmeyi bile teklif ediyor) İşte böyle yaşıyoruz ...

 
Alexey Navoykov :

Kesinlikle. Bu aynısı.

Böylece, bir problemin gerçekten mümkün olduğu ve en azından uyarılara ihtiyaç duyulduğu (ve genel olarak bir derleme hatası ) olduğu ortaya çıktı, o zaman hiçbir şey verilmez. Ancak parantezlerin dayatılmasıyla uyarıları boşa çıkarmazlar) Ve burada bazıları parantez olmadan derlemeyi yasaklamayı ve hatta kelepçelerle tehdit etmeyi bile teklif ediyor) İşte böyle yaşıyoruz ...

Peki hala uyarılara ihtiyacınız var mı? Ne tür bir çifte standart: her iki yerde de davranış net, ancak parantez içinde uyarılara karşısınız, ama burada - İÇİN?

Ayrıca ince hatalar yapmamak için bir uyarıya ihtiyacınız var. Dolayısıyla zorluk öznel bir değerlendirmedir. Burada parantez ile hata yapmazsınız, ancak burada yapabilirsiniz. Ve benim için tam tersi.

Peki hangimiz uyarı vermek için kuralları uyarlamalıyız?

 
Ilya Malev :

StringConcatenate'i bilmiyordum, MT5'te yeniden yapılmış olması ve artık string s olmadan kullanılamaması üzücü. Ve dördüncüsünde, StringFormat gözle görülür şekilde daha hızlı çıkıyor

Ve genel olarak, herhangi bir nedenle, ilk beşte, bir işaretçiyi bir dize aracılığıyla "basitleştirme" işlemi neredeyse iki kat daha yavaştır, ancak temelde her şey orada daha hızlı, bazen bir büyüklük sırasına göre daha hızlı çalışır.

StringConcatenate() bir nedenden dolayı 32-bit olabilir, kim bilir, geliştiriciler zaten 5'te aynı olan, 4'te aynı olan Metaetitors'un uyumluluk nedeniyle "sarılmış" olabileceğini yazmışlardır.

dynamic_cast<> ile deney yapabilirsiniz, dün sorununuzu çözmeye çalıştım, ancak sorun şu ki, MQL işaretçilerin başvurularının kaldırılmasına izin vermiyor, dinamik_cast<C_myclass >( func( ) ) aracılığıyla bir işleve bir işaretçi alabilirsiniz. belirli bir sınıf yöntemi, böylece onu çağırarak, dynamic_cast<> aracılığıyla bir sınıfa bir işaretçi alabilirsiniz, ancak böyle bir işaretçiyle ne yapmalı? - void *ptr öğesini yeniden atayabilirsiniz, ancak bu mantıklı değil, yine de bir işaretçinin başvurusunu kaldıramazsınız

 
pavlick_ :

Döküğe bir CArayObject göndermek istiyorsanız, temel sınıf üzerinde bir sarmalayıcı (bunun gibi https://www.mql5.com/ru/forum/170952/page110#comment_9894796) yapmanız ve bunları bir dizi (belki sizinki), ancak o zaman void*'e ihtiyacınız yoktur.

Boşluğa karşı değilim*, gerekli ama farklı bir kapasitede.

Kodun amacını referans olarak görmüyorum (standart kitaplıkları kullanmama rağmen). Bir nesneyi bir diziye yerleştirmek onun bir kopyasını oluşturmayı içeriyorsa, atama yöntemi veya kopya oluşturucu bu sınıfta açıkça bildirilmeli ve tanımlanmalıdır, aksi takdirde hiçbir sarmalayıcı yine de yardımcı olmaz. Bir dizideki bir nesneye yalnızca bir başvuru koymanız gerekiyorsa, sarmalayıcı gerekmez (neden birdenbire?)

Bu arada, if(p) delete p'nin mql'de aynı olmadığını bilmiyor gibisiniz "referans mevcut bir dinamik nesneye işaret ediyorsa, onu silin"

 class A{};

void OnStart ()
 {
  A *a= new A;
   if (a) Print ( "Кукареку!" );
   if ( CheckPointer (a)== POINTER_DYNAMIC ) Print ( "Динамический объект существует и может быть удален" );
   else                                  Print ( "Объект не существует, либо он автоматический" );
   delete a;
   if (a) Print ( "Кукареку!" );
   if ( CheckPointer (a)== POINTER_DYNAMIC ) Print ( "Динамический объект существует и может быть удален" );
   else                                  Print ( "Объект не существует, либо он автоматический" );
 }
 
fxsaber :

Ve görünürlük hakkında

Hangisi daha iyi diye soralım.

Peki, stilist sizi şöyle biçimlendirdiyse:

 1 < 2 && 3 < 4 ;

o zaman, tüm soruları bu stiliste tekrar ediyorum. Bu yüzden hasta bir kafayı sağlıklı bir kafaya suçlamaya gerek yok. Bunu asla kodumda yapmazdım. Ve bunu yapardım:

 1 < 2 && 3 < 4
либо
1 < 2   &&   3 < 4