Genel sınıflar kütüphanesi - hatalar, açıklamalar, sorular, kullanım özellikleri ve öneriler - sayfa 29

 
Alexey Volchanskiy :

MSDN'de buna halka arabelleği denir, ancak bir isim bulamadım.

stüdyo bağlantısı

Alexey Navoykov :

...ve argümanlar için sadece değere göre değil, referansa göre yeniden çalışmakla bitiyor.

literallerle ilgili sorunlar olabilir

 
TheXpert :

stüdyo bağlantısı

literallerle ilgili sorunlar olabilir

O makaleyi tekrar aramak için çok tembel ama biraz batırdım. Dairesel bir veya iki bağlantılı liste, bağlantılı liste temelinde oluşturulur, ancak ilkinin bağlantısı son öğede saklanır.

 
TheXpert :

literallerle ilgili sorunlar olabilir

Evet, hayır, sınıf "değerlerim", yalnızca bir sarmalayıcı olarak temel sınıf "referanslarından" miras alınır. Bu nedenle, sadece sınıfın gerekli sürümünü seçiyoruz - ve iletiyoruz
 
Alexey Volchanskiy :

Dairesel bir veya iki bağlantılı liste, bağlantılı liste temelinde oluşturulur, ancak ilkinin bağlantısı son öğede saklanır.

Yani meselenin gerçeği, karşılığında değil, "temelde" inşa edilmesidir. Geliştiricilerin bunu ek bir kapsayıcı olarak yapmasını kimse engellemedi. Geleneksel bilgeliği değiştirmeyin
 
Alexey Navoykov :

Büyük olasılıkla, bu sınıfları taşıyan kişi, kodu basitleştirerek hayatı kendisi için kolaylaştırmaya karar verdi. İki işaretçi m_first ve m_last yerine, bir işaretçi m_head yaptım ...

Dotnet kaynaklarına baktı ve nedenini anladı. LinkedList sınıfının kendisi doğru bir şekilde taşınır, gerçekten hem başlangıç hem de son olan yalnızca bir baş işaretçi vardır. Onlar. iç uygulama gerçekten döngülüdür. Ama dış davranış öyle değil. MQ'nun CLinkedNode sınıfında bir hatası var (Sonraki ve Önceki yöntemler). İşte orijinal uygulamalarının nasıl göründüğü:

         public LinkedListNode<T>? Next
        {
             get { return next == null || next == list!.head ? null : next; }
        }

         public LinkedListNode<T>? Previous
        {
             get { return prev == null || this == list!.head ? null : prev; }
        }

Ve işte MQL'ye nasıl taşındığı:

   CLinkedListNode<T>* Next( void )                      { return (m_next); }
   CLinkedListNode<T>* Previous( void )                  { return (m_prev); }

Belki yanlışlıkla karıştırılmıştır.

Ancak genel olarak, dotnet'teki uygulama konusunda da biraz şaşırdım. Neden bir kafa yerine listenin kendisinde (ilk ve son) iki işaretçi yapmıyorsunuz? Bu, liste düğümünün yukarıdaki yöntemlerinde gereksiz kontrolleri önleyecektir, yani. şimdi tam olarak MQ gibi görüneceklerdi, ama her şey düzgün çalışacaktı. Elbette bu, düğüm ekleme/silme sürecini biraz yavaşlatacak, ancak bunlar üzerinde yinelemeyi önemli ölçüde hızlandıracak, ki bu çok daha önceliklidir. Sonraki ve Önceki, kuşkusuz, düğümlerin eklenmesinden daha sık çağrılır. Bunu sadece kendim için yaptım, küçük yumuşak olanlar için benzer olacağını düşündüm. Neyse )

Bu arada, MQ'nun CLinkedListNode ve CRedBlackTreeNode uygulamasında bir sövesi daha var. Alanları m_next, m_prev, vb. (m_value hariç) yalnızca liste sınıfının kendisi tarafından değiştirilmek üzere tasarlanmıştır. Onları başka kimse değiştirmemeli. Bu nedenle, dotnet'te bunlar dahili alanlardır. Yalnızca get yöntemleri kullanıcıya açıktır. Ve bazı nedenlerden dolayı, MQ bu alanları değiştirmek için herkese açık yöntemler yaptı ve en azından onları bir şekilde özel olarak adlandırsalar iyi olurdu ... ama hayır, normal isimler:

 void               Next(CLinkedListNode<T>* value )     { m_next= value ; }
 

Merhaba!

CHashMap'teki öğeleri silmenin CopyTo'yu kullanmak ve bunları manuel olarak silmek dışında başka bir yolu var mı?

 

Kütüphane uygulama eğrisinin fırınında birkaç yakacak odun daha var. Bazı nedenlerden dolayı, CKeyValuePair sınıfları IComparable arabirimini (ve buna bağlı olarak IEqualityComparable'ı) devralır ve özel Anahtar türünün de bu arabirimleri desteklemesini gerektirir. Buna rağmen buna gerek yok eğer kendi Karşılaştırıcımızı tanımlarsak. Orijinalinde, elbette, KeyValuePair'in herhangi bir arayüzü yoktur.

İçini kazmaya devam ettikçe daha da garip şeyler keşfedersiniz:

 template < typename TKey, typename TVal>
CHashMap::CHashMap(IEqualityComparer<TKey>*comparer): m_count( 0 ),
                                                      m_free_list( 0 ),
                                                      m_free_count( 0 ),
                                                      m_capacity( 0 )
  {
//--- check equality comaprer
   if ( CheckPointer (comparer)== POINTER_INVALID )
     {
       //--- use default equality comaprer    
      m_comparer= new CDefaultEqualityComparer<TKey>();
      m_delete_comparer= true ;
     }
   else
     {
       //--- use specified equality comaprer
      m_comparer=comparer;
      m_delete_comparer= false ;
     }
  }

Onlar. yanlışlıkla bozuk bir işaretçiyi yapıcıya iletirseniz, program sadece sessizce çalışmaya devam etmeyecek, aynı zamanda mantık da değişecektir! Evet...

Yapıcı şöyle görünmelidir:

 template < typename TKey, typename TVal>
CHashMap::CHashMap(IEqualityComparer <TKey> *comparer): m_count( 0 ),
                                                      m_free_list( 0 ),
                                                      m_free_count( 0 ),
                                                      m_capacity( 0 ),
                                                      m_comparer(comparer),
                                                      m_delete_comparer( false )
{ }

Ve POINTER_INVALID yok. Ve varsayılan karşılaştırıcı için başka bir kurucu imzası var.

 
T parametresi olarak rastgele bir sınıfla CQueue<T> şablonunun nasıl doğru şekilde uygulanacağına dair bir örnek var mı?
 
Zaten paralel bir iş parçacığında. Yasak isteyin.
 

Kodun neden derlenmediğini söyleyebilir misiniz?

 #include <Generic\HashMap.mqh>
void OnStart ()
  {
   CHashMap< ENUM_CHART_PROPERTY_INTEGER , int > mapI;     // эта срока компилируется без ошибок
   CHashMap< ENUM_CHART_PROPERTY_DOUBLE , double > mapD;   // здесь ошибки компиляции: 'NULL' - cannot convert enum  HashMap.mqh     21      39. 'NULL' - cannot convert enum        HashMap.mqh     462     30
   CHashMap< ENUM_CHART_PROPERTY_STRING , string > mapS;   // здесь ошибки компиляции: 'NULL' - cannot convert enum  HashMap.mqh     21      39. 'NULL' - cannot convert enum        HashMap.mqh     462     30

  }

Sorun sistem numaralandırmalarındadır: ENUM_CHART_PROPERTY_DOUBLE, ENUM_CHART_PROPERTY_STRING onlarla ilgili bir sorun var. Anahtar türü olarak kendi numaralandırmanızı kullanırsanız, derleme de   geçer.