Yazma hakkında soru

 

Sevgili programcılar, uzun zamandır bu soruyla kafamı karıştırıyorum. İşlevin dönüş değerini bir şekilde tasarlamak ve örtük olarak yazmak mümkün müdür? Yöntem çağrıları harici olarak aynı olduğunda, bir sınıf yönteminin farklı türde bir değer döndürmesi için.

 void OnStart ()
 {
  CParameter p1 = Ask , p2 = Bid , p3 = TimeCurrent (), p4 = TimeLocal ();
  
   // Перегруженный в CParameter оператор ~ возвращает преобразованное в строку значение известного объекту типа
  
   printf ( "p1=%s, p2=%s, p3=%s, p4=%s" , ~p1, ~p2, ~p3, ~p4 );
  
   // А можно ли исхитриться и сделать вот так (допустим это будет перегруженный тем или иным образом оператор !, возвращающий
   //   значение нужного типа в зависимости от type. 
   //
   // double ask = !p1, bid = !p2;
   // datetime current = !p3, local = !p4;  
 }  

Bu sınıfın kendisi, soru açıksa izleyemezsiniz.

 enum TYPE{ NUMBER, PRICE, TIME };

class CParameter
 {
public :
   template < typename T> void operator = ( T par )
   {
     if ( typename ( T ) == " double " )
     {
      data = int ( double ( par ) * 100000 );
      type = PRICE;
     }
     else
     {
       if ( typename ( T ) == " datetime " )
       {
        data = int ( uint ( par ) );
        type = TIME;
       }
       else
       {
        data = int ( par );
        type = NUMBER;
       }
     }
   }
   
   double to_price()
   {
     switch (type)
     {
       case PRICE: return double ( data ) / 100000 ;
       case TIME:   return MathArcsin ( 2.0 );
       default :     return double ( data );
     }
   }

   datetime to_time()
   {
     switch (type)
     {
       case TIME:   return datetime ( data );
       default :     return 0 ;
     }
   }

   int to_number()
   {
     switch (type)
     {
       case PRICE: return int ( double ( data ) / 100000 );
       case TIME:   return 0 ;
       default :     return data;
     }
   }
   
   string to_string()
   {
     switch (type)
     {
       case PRICE: return DoubleToString ( to_price(), 5 );
       case TIME:   return TimeToString ( to_time(), TIME_DATE | TIME_SECONDS );
       default :     return IntegerToString ( data );
     }
   }
   
   string operator ~ ()
   {
     return to_string();
   }
   
private :
   int data;
  TYPE type;
 };
 

Ayrıca atama yaparken swich'ten kurtulabilir ve aşırı yüklemeden yararlanabilirsiniz:

   void operator =( double par){
      data = int ( double (par)* 100000 );
      type = PRICE;
   }
   void operator =( datetime par){
      data= int ( uint (par));
      type=TIME;
   }
   void operator =( int par){   
      data = int (par);
      type = NUMBER;
   }

Ardından, döndürülen değer bir aritmetik işlem için kullanılacaksa (neye odaklanılacak), o zaman şöyle bir şey:

   string operator +( string par){
       return to_string()+par;
   }
   
   double operator +( double par){
       return to_price()+par;
   }   
   
   double operator +( int par){
       return to_number()+par;
   }  
 Print (p1+ 1 );
Print (p1+ 1.0 );
Print (p1+ "1" );

---

Kendim için olsaydı, referans olarak bir parametre üzerinden dönüş ile aşırı yüklenmiş fonksiyonlar yapardım.

   void r( double & v){
      v=to_price();
   }
   void r( int & v){
      v=to_number();
   }   
   void r( string & v){
      v=to_string();
   }   
 
Dmitry Fedoseev :

Ayrıca atama yaparken swich'ten kurtulabilir ve aşırı yüklemeden yararlanabilirsiniz:

Ardından, döndürülen değer bir aritmetik işlem için kullanılacaksa (neye odaklanılacak), o zaman şöyle bir şey:

Açık aşırı yükleme ve aritmetik eylemlerle her şey açıktır. Evet, aşırı yüklenmiş = bu durumda açıkça daha başarılı, doğru fark ettiniz, sadece bir soru için aceleyle bir örnek oluşturdum ve gerçekten düşünmedim (sayı sadece int değil, aynı zamanda char, uchar, short, ushort, uint, bool ve color, yani her şey açık değil))))))

Dmitry Fedoseev :

Eğer kendimi referans olarak bir parametre üzerinden bir dönüşle aşırı yüklenmiş fonksiyonlar yapsaydım.


Burada soru, aşırı yüklenmiş yöntemin dönüş türünün nesnenin içeriğine bağlı olmasıdır.

Örneğin bir multi-type dizimiz var (çoklu kitap olduğu için örnek vermeyeceğim). Ve elbette, herhangi bir dizide, karşılık gelen dizine sahip değişkenin değerini döndüren bir dizin oluşturma işlemi [] olmalıdır.

Ancak değişkenlerin farklı türleri vardır. Bu dizin altında bir tarih olabilir veya bir dize veya hatta bazı özel türler olabilir. Ve ideal olarak, [] dizine eklerken dönüş değerinin türünün, açıkça parametreleştirmeye gerek kalmadan otomatik olarak karşılık gelen türü üretmesini isterim. Daha önce, bu "problemi" şu şekilde çözmüştüm: var[(char)1], var[(short)1], var[(uint)1], vb. ama bu koltuk değnekleri iyi değil.

 
void OnStart()
 {
  CParameter<double> p1 = Ask;
  CParameter<double> p2 = Bid;
  CParameter<datetime> p3 = TimeCurrent();
  CParameter<datetime> p4 = TimeLocal();
  
  // Перегруженный в CParameter оператор ~ возвращает преобразованное в строку значение известного объекту типа
  
  printf( "p1=%s, p2=%s, p3=%s, p4=%s", ~p1, ~p2, ~p3, ~p4 );
  
  // А можно ли исхитриться и сделать вот так (допустим это будет перегруженный тем или иным образом оператор !, возвращающий
  //   значение нужного типа в зависимости от type. 
  //
   double ask = !p1, bid = !p2;
   datetime current = !p3, local = !p4;  
 }  
template <typename T>
class CParameter
 {
public: 
  void operator =( const T Value )
  {
    this.data = Value;
  }

  string operator~( void) const
   {
    return((string)this.data);
   }
   
  T operator !( void ) const
  {
    return(this.data);
  }  
   
private:
  T data;
 };
 
fxsaber :

Bu durumda, p1'e p4'ün değerini atamayacaksınız (bir tip değişikliği ile), ancak bu prensipte mümkün olmalıdır. ayrıca, nesneler aynı tipte olmalıdır.

Peki, ya da bir dizi durumunda - bir tabana sahip farklı türde nesneler, ancak dizi nesnesinin kendisinin, dönüş türü ilgili dizine sahip nesnenin türüne bağlı olan bir yöntemi vardır.
 
benzer bir soru: neden, bir yöntem aşırı yüklenirken ( aşırı yüklenmiş bir yöntemin imzasında ), dönüş türü görünmüyor, yalnızca parametre türleri görünüyor. yani, farklı dönüş türleriyle iki özdeş yöntem tanımlayamazsınız. neden böyle bir kısıtlama var? bunun anlamı nedir, aynı parametrelerle dönüş değerinin türüne göre yöntemi aşırı yüklemek neden imkansız
 
Ilya Malev :

Bu durumda, p1'e p4'ün değerini atamayacaksınız (bir tip değişikliği ile), ancak bu prensipte mümkün olmalıdır. ayrıca, nesneler aynı tipte olmalıdır.

Peki, ya da bir dizi durumunda - bir tabana sahip farklı türde nesneler, ancak dizi nesnesinin kendisinin, dönüş türü ilgili dizine sahip nesnenin türüne bağlı olan bir yöntemi vardır.

https://www.mql5.com/ru/docs/constants/structures/mqlparam

Документация по MQL5: Константы, перечисления и структуры / Структуры данных / Структура входных параметров индикатора
Документация по MQL5: Константы, перечисления и структуры / Структуры данных / Структура входных параметров индикатора
  • www.mql5.com
каждого элемента этого массива указывает тип данных, передаваемых данным элементом. Сами значения параметров индикатора необходимо предварительно поместить в соответствующие поля каждого элемента (в...
 

peki, evet, vakaların% 90'ında 4 yeterli olduğunda 32 bayt aktarın ... genel olarak, bu dalın sorusu değil, sırayla ilgileniyorum - belki biri açıklananda az çok zarif bir çözüm buldu durum


ps ayrıca, soru hiçbir şekilde farklı türlerdeki verileri tek bir nesnede/yapıda depolamakla ilgili değildir.

 
Ilya Malev :
benzer bir soru: neden, bir yöntem aşırı yüklenirken ( aşırı yüklenmiş bir yöntemin imzasında ), dönüş türü görünmüyor, yalnızca parametre türleri görünüyor. yani, farklı dönüş türleriyle iki özdeş yöntem tanımlayamazsınız. neden böyle bir kısıtlama var? bunun anlamı nedir, aynı parametrelerle dönüş değerinin türüne göre yöntemi aşırı yüklemek neden imkansız

Yöntem, hangi türün döndürüleceğine karar veremez.

 
fxsaber :

Yöntem, hangi türün döndürüleceğine karar veremez.

Başka bir deyişle, yazdıklarımı tekrar ettin. Soru, yapıp yapamayacağı değil, neden yapamadığı ve onu zarafetle nasıl aşacağıydı.

 
Ilya Malev :

Başka bir deyişle, yazdıklarımı tekrar ettin. Soru, yapıp yapamayacağı değil, neden yapamadığı ve onu zarafetle nasıl aşacağıydı.

Tip kontrolü kayboldu. Bu soruların yanıtları için C++ kaynaklarına bakın. Sanırım çok sık soruluyorlar.