Hatalar, hatalar, sorular - sayfa 1951

 
Stanislav Korotky :

Bir işlevden bir nesnenin adsız bir örneğini döndürmenin herhangi bir yolu var mı?

Makro ile değiştirin.
 
fxsaber :
Makro ile değiştirin.

Çalışmayacak. Bu bir sınıf yöntemidir ve param aslında nesneden alınır. Burada, örneğin, basitleştirdim.

 
Stanislav Korotky :

Çalışmayacak. Bu bir sınıf yöntemidir ve param aslında nesneden alınır. Burada, örneğin, basitleştirdim.

Tabii ki, orijinal problemle tanışmak daha iyidir ...

İşaretçiyi döndürmek için - bu olmayacak mı?

 

Stanislav Korotky :

Fazladan bir dahili kopya oluşturması dışında çalışır ve dönüş ifadesi sınıfta bir kopya oluşturucu gerektirir. İşlev çıktığında kopya çivilenmiş olsa da, kopyalamanın kendisini hariç tutmak istiyorum.


Class function()
{
   int param = 0 ;
  Class obj(param);
   return obj;
}

Tabii ki, fonksiyondan çıktıktan sonra yerel değişkenin yok edilmesini gerektirir.
Yeni kullanın ve bir işaretçi döndürün, sorun nedir?

Kaynak denetimi gerekiyorsa, akıllı işaretçi benzeri bir sarmalayıcı kullanın.
Belki singleton veya builder gibi Yaratılış Kalıpları olan bir şey size uyacaktır, ...

 
fxsaber :

Tabii ki, orijinal problemle tanışmak daha iyidir ...

İşaretçiyi döndürmek için - bu olmayacak mı?

Başlangıçta işaretlerde bu vardı. Ancak daha sonra bunları kaldırmaktan müşteri kodu sorumludur ve bir göz açıp kapayıncaya kadar ve sarkan bağlantıların kaldığı gerçeğinden bahsetmiyorum bile, çok fazla çöp.

 
Sergey Dzyublik :

Tabii ki, fonksiyondan çıktıktan sonra yerel değişkenin yok edilmesini gerektirir.

Yeni kullanın ve bir işaretçi döndürün, sorun nedir?

Kaynak denetimi gerekiyorsa, akıllı işaretçi benzeri bir sarmalayıcı kullanın.
Belki singleton veya builder gibi Yaratılış Kalıpları olan bir şey size uyacaktır, ...

İşaretçiler var - uygun değil (yukarıda cevaplandı). "Akıllılara" bakmaya çalıştım. Ancak, MQL için akıllı bir işaretçinin yalnızca bir referans düzeyi daha vereceği ve bunun da izlenmesi gerekeceği izlenimini edindim. Sonuçta, akıllı işaretçi nedir? orijinal bağlantıyı içeren bir sarmalayıcı nesnedir. Ve ambalajı kim ve ne zaman temizleyecek? ;-) Hazır çözümler varsa, kişisel bir plizde atın. Devam eden bir test vakam var.

 
Stanislav Korotky :

Sonuçta, akıllı işaretçi nedir? orijinal bağlantıyı içeren bir sarmalayıcı nesnedir. Ve ambalajı kim ve ne zaman temizleyecek? ;-) Hazır çözümler varsa, kişisel bir plizde atın. Devam eden bir test vakam var.


Shared_ptr'yi kullanın.
Bu sarmalayıcının temizlenmesi gerekmez, kopyalanması gerekir ve gerekli kaynağa sahip kaç örnek kaldığı ve şu veya bu kaynağın ne zaman serbest bırakılacağı, share_ptr'nin özüdür.


En azından benim için hazır çözümler yok. C++-snye'yi uyarlayın.

 
Sergey Dzyublik :

En azından benim için hazır çözümler yok. C++-snye'yi uyarlayın.

Bu anlaşılabilir bir durumdur - yaptığım şey bu, ancak MQL'nin bir "aydınger kağıdı" yapmanıza izin vermeyeceği izlenimini edindim.

 
Stanislav Korotky :

Bir işlevden adsız bir nesne örneği döndürmenin bir yolu var mı?

Burada daha önce belirtildiği gibi, en doğru yol, işlevden bir akıllı işaretçi döndürmektir. Bütün bunlar MQL'de uygulanmaktadır. Doğru, kullanımı C ++ kadar uygun değil, çünkü işaretçi ile geçişin bir geçiş operatörü aracılığıyla değil, bir yöntem aracılığıyla uygulanması gerekecek. Bu arada, söz konusu görev için, mutlaka paylaşılan_ptr değil, benzersiz_ptr'nin yeterli olduğuna inanıyorum.

Peki ya da bir seçenek olarak, böylece fonksiyon içinde oluşturulan işaretçi hemen programın sonunda temizlenecek olan belirli bir global diziye yerleştirilir. Bu durumda, kullanıcı herhangi bir zamanda özel bir fonksiyon çağırarak (silme değil) nesnenin hafızasını boşaltabilir. WinApi'deki CloseHandle'a benzer.

Fazladan bir dahili kopya oluşturması dışında çalışır ve dönüş ifadesi sınıfta bir kopya oluşturucu gerektirir. İşlev çıktığında kopya çivilenmiş olsa da, kopyalamanın kendisini hariç tutmak istiyorum.

Belki de derleyici, gereksiz kopyalamayı ortadan kaldırarak her şeyi kendi başına optimize edip satır içi yapacak kadar akıllıdır. Ama bunun kontrol edilmesi gerekiyor. Birisi testler ve ölçümler yapsa iyi olurdu. Ve sonra ben de sık sık böyle bir ikilem beni şaşırttı.

 
Alexey Navoykov :

Burada daha önce belirtildiği gibi, en doğru yol, işlevden bir akıllı işaretçi döndürmektir. Bütün bunlar MQL'de uygulanmaktadır. Doğru, kullanımı C ++ kadar uygun değil, çünkü işaretçi ile geçişin bir geçiş operatörü aracılığıyla değil, bir yöntem aracılığıyla uygulanması gerekecek. Bu arada, söz konusu görev için, mutlaka paylaşılan_ptr değil, benzersiz_ptr'nin yeterli olduğuna inanıyorum.

Peki ya da bir seçenek olarak, böylece fonksiyon içinde oluşturulan işaretçi hemen programın sonunda temizlenecek olan belirli bir global diziye yerleştirilir. Bu durumda, kullanıcı herhangi bir zamanda özel bir fonksiyon çağırarak (silme değil) nesnenin hafızasını boşaltabilir. WinApi'deki CloseHandle'a benzer.

Belki de derleyici, gereksiz kopyalamayı ortadan kaldırarak her şeyi kendi başına optimize edip satır içi yapacak kadar akıllıdır. Ama bunun kontrol edilmesi gerekiyor. Birisi testler ve ölçümler yapsa iyi olurdu. Ve sonra ben de sık sık böyle bir ikilem beni şaşırttı.

Uygulamamı aşağıda yayınlıyorum - aynı şekilde, bu akıllı işaretçiler geçici olarak oluşturulur ve sonuç olarak ;-) olduğundan daha fazla nesne basitçe oluşturulur ve çivilenir.

Tabii global dizi seçeneği de aklımda ama ne kadar çirkin! Ayrıca, zamanlayıcı ile temizlemek istedim (çünkü program günlerce çalışabilir) ve MQL'deki zamanlayıcı bir sınıfa/nesneye bağlanamaz - yalnızca global işleyiciden alınır.

Derleyici burada yardımcı olmaz - kontrol edilir - yerel nesne iade ile çoğaltılır ve ardından çivilenir. Bu durumda optimal bir hareket yoktur.

 template < typename T>
class auto_ptr
{
   private :

     class Reference
    {
       public :
         int count;
        Reference(): count( 0 ) {}
    };

    T *data;
    Reference *reference;

    void remove()
    {
      if(reference != NULL)
      {
        reference.count--;
        if(reference.count == 0)
        {
          delete data;
          delete reference;
        }
      }
    }

    
   public :
    auto_ptr(): data( NULL ), reference( NULL )
    {
    }
    auto_ptr(T *ptr): data(ptr), reference(ptr == NULL ? NULL : new Reference())
    {
       if (reference != NULL ) reference.count++;
    }
    auto_ptr(auto_ptr<T> &ref): data(ref.data), reference(ref.reference)
    {
      reference.count++;
    }
    
    ~auto_ptr()
    {
      remove();
    }
    
     void operator =(auto_ptr<T> &next)
    {
       if (& this != &next)
      {
        remove();
        
        data = next.data;
        reference = next.reference;
        reference.count++;
      }
    }
};