OOP. Başvuru soruları - sayfa 4

 
Yedelkin :

Soru. Belirli bir parametre seti ve türleri ile üst sınıfta bir sanal işlev bildirdikten sonra, alt sınıflardaki karşılık gelen sanal işlevler için parametre sayısını ve türünü değiştirmek mümkün müdür?

Bir yandan, Referans, " türetilmiş bir sınıfta sanal bir işlev geçersiz kılınabilir. Bir sanal işlev için hangi işlev tanımının çağrılacağı seçimi dinamiktir (çalışma zamanında). Tipik durum, temel sınıfın aşağıdakileri içermesidir , ve türetilmiş sınıfların bu işlevin kendi sürümleri vardır. Öte yandan, El Kitabında verilen örnekler, sanal işlevlerin işlev tanım başlıklarında değil, işlev tanım gövdelerinde farklılık gösterdiği durumlarla ilgilidir.

Hatırladığım kadarıyla. Ancak, parametre türleri ve sayısında kesinlikle bir zhoskoe farkına ihtiyacınız var.

Bu geçirilen değerlere ve varsayılan değerlere de dikkat etmelisiniz.

Basit olması için örnekler vereceğim.

Bu seçenek işe yarayacak

boll MyFunction( int Param);
boll MyFunction( int Param1, int Param2);

Böyle bir şey yok (ya da daha doğrusu yuvarlanabilir, ancak hatalar ve belirli çekincelerle)

 //Ели второй параметр будет упущен, то компилятор может и не "понять" смысла всего задуманного
boll MyFunction( int Param);
boll MyFunction( int Param1, int Param2 = 0 );
//Так тоже может не прокатить по причине совпадения типов у второго параметра
boll MyFunction( int Param1, color Param2);
boll MyFunction( int Param1, int Param2);

Bir sınıfta RELOAD yöntemi varsa, kesinlikle aynı çöp oluşturulur.

 
mql5 :
Varsayılan seçenekler dışında tanımın tam bir kopyası (varsayılanlar değişebilir, ancak bunu kullanmamak en iyisidir)
"Yalnızca tanım başlığının tam bir kopyası" mı demek istiyorsunuz? Sonuçta , bir işlev tanımı bir başlık artı bir gövde içerir. Örneklerdeki bedenler tamamen farklıdır.
 

İlginç , anladığım kadarıyla işlev sanallaştırma ve işlev aşırı yüklemesi biraz farklı şeyler. Ve mql5 , işlevleri sanallaştırırken, işlev başlığının basılı bir kopyasının olması gerektiğini söylüyor (varsayılan parametreleri hesaba katmıyorum).

 
Yedelkin :

İlginç , anladığım kadarıyla işlev sanallaştırma ve işlev aşırı yüklemesi biraz farklı şeyler. Ve mql5 , işlevleri sanallaştırırken, işlev başlığının basılı bir kopyasının olması gerektiğini söylüyor (varsayılan parametreleri hesaba katmıyorum).

> Soru. Belirli bir parametre seti ve türleri ile üst sınıfta bir sanal işlev bildirdikten sonra, alt sınıflardaki karşılık gelen sanal işlevler için parametre sayısını ve türünü değiştirmek mümkün müdür?

Her şeyi doğru anlarsam, soyundan gelen, ataların işlevselliğini aşırı yüklemelidir.

Dürüst olmak gerekirse, sanal olanlarla benzer şeyler yapıp yapmadığımı hatırlamıyorum (sanırım yaptım), ancak aşırı yüklenmeyle ilgili ifade doğru - kendim bir kez bu komisyona bastım.

not

Her şey doğru yapılırsa, anladığım kadarıyla parametre sayısı hem artırılabilir hem de azaltılabilir. Zorluklar, parametre sayısı aynı kalırsa, ancak türleri değişirse olacaktır ...

 

Genel olarak, aşağıdaki örneği çizdim:

 class C_A             //родительский класс
{
 public :
 virtual double function( double a1, double a2, double a3) { return ; }
}
class C_B : public C_A
{
 public :
 virtual double function( double a1, double a2, double a3) { return (a1);   }
}
class C_C : public C_A
{
 public :      
 virtual double function( double a1, double a2, double a3) { return (a2);   }
        double function( double a1, double a2)           { return (a1+a2); }
}
//где-то в программе объявляем указатель
C_A  *pointer;
int random= rand ()%2;
   switch (random)
     {
       case 0 : pointer= new C_B; break ;
       case 1 : pointer= new C_C; break ;
     }

//вызываем виртуальный метод
   if (pointer!= NULL )
     {
      pointer.function(a1,a2,a3);
     }

C_C sınıfındaki işlev yönteminin aşırı yüklenip yüklenmediğine bakılmaksızın, sanal bir işlevin yalnızca üç parametreyle çağrılabileceği ortaya çıktı - pointer.function(a1,a2,a3). Buna göre program, sanal işlevleri çağırırken hiçbir zaman C_C sınıfından iki parametreli yönteme ulaşmayacaktır. Doğru şekilde?

 
Yedelkin :

Temel olarak, işte bir örnek:

C_C sınıfındaki işlev yönteminin aşırı yüklenip yüklenmediğine bakılmaksızın, sanal bir işlevin yalnızca üç parametreyle çağrılabileceği ortaya çıktı - pointer.function(a1,a2,a3). Buna göre program, sanal işlevleri çağırırken hiçbir zaman C_C sınıfından iki parametreli yönteme ulaşmayacaktır. Doğru şekilde?

Programın __FUNCTION__ makrosu ile baskıları yapıcılara ve yıkıcılara ekleyerek ne yaptığını analiz edin, çok faydalı olacaktır.

Kendi adıma, bir temel sınıf işaretçisi bildirerek, alt sınıf aracılığıyla alt sınıflara bir "tünel" geçişi oluşturduğunuzu ekleyeceğim. Böylece, derleyici, soyundan gelenlere böyle bir çağrı ile, soyundan gelenlerde yalnızca temel sınıfta bildirilen işlevleri görecektir. Siz (aynı program içinde bile) doğrudan bir alt nesne bildirirseniz, tüm işlevler içinde kullanılabilir olacaktır.

 class C_A             //родительский класс
{
 public :
 virtual double function( double a1, double a2, double a3) { return ; }
}
class C_B : public C_A
{
 public :
 virtual double function( double a1, double a2, double a3) { return (a1);   }
}
class C_C : public C_A
{
 public :      
 virtual double function( double a1, double a2, double a3) { return (a2);   }
         double function( double a1, double a2)           { return (a1+a2); }
}
//где-то в программе объявляем указатель
C_A  *pointer;
int random= rand ()% 2 ;
   switch (random)
     {
       case 0 : pointer= new C_B; break ;
       case 1 : pointer= new C_C; break ;
//вызываем виртуальный метод
   if (pointer!= NULL )
     {
      pointer.function(a1,a2,a3);
     }
C_С  *new_pointer= new C_C;
      new_pointer.function(a1,a2);
 
Yedelkin :

Genel olarak, aşağıdaki örneği çizdim:

C_C sınıfındaki işlev yönteminin aşırı yüklenip yüklenmediğine bakılmaksızın, sanal bir işlevin yalnızca üç parametreyle çağrılabileceği ortaya çıktı - pointer.function(a1,a2,a3). Buna göre program, sanal işlevleri çağırırken hiçbir zaman C_C sınıfından iki parametreli yönteme ulaşmayacaktır. Doğru şekilde?

Kendi deneyimlerime göre, kodu tamamlamak için bu yolu önerebilirim

 double function( double a1, double a2)            { return (a1+a2);}
double function( double a1, double a2, double a3) { return (a2);}

Ve bir örnek ve eğlence olarak, ekteki dosyayı görebilirsiniz.

İşaretçiler ve yeni ile ortalığı karıştırmak için bir av değildi, bu yüzden işçi sınıfını bir değişken olarak ilan ettim.

Zamanlayıcı Uzman Danışmanı, düzenli aralıklarla rastgele bir 0/1 sayısı üretir ve sonuca bağlı olarak iki işlevden birini gerçekleştirir: MarketBuy / MarketSell.


İstenirse böyle beyan etmek mümkündü.

 bool MarketBuy( string SymbolTitle, double LotSize, double TP = 0.0 , double SL = 0.0 );
bool MarketSell( string SymbolTitle, double LotSize, double TP = 0.0 , double SL = 0.0 );

Ama sonra bir çatışma hakkında bir hata ortaya çıkabilir

 bool MarketBuy( string SymbolTitle, double LotSize);
bool MarketSell( string SymbolTitle, double LotSize);


not

Acele yapıldı, bu yüzden bazı yanlışlıklar olabilir.

Ancak prensipte ana fikir anlaşılabilir.

Dosyalar:
Forum.mq5  18 kb
 

Değerli ipuçlarınız ve tavsiyeleriniz için çok teşekkür ederiz ! Hem teori hem de pratik için yeterli zamanım olsaydı kesinlikle kullanacağım.

Interesting :

Kendi deneyimlerime göre, kodu tamamlamak için bu yolu önerebilirim

 double function( double a1, double a2)            { return (a1+a2);}
double function( double a1, double a2, double a3) { return (a2);}
Neden tam olarak? tuzak nedir?
 
Yedelkin :

Neden tam olarak? tuzak nedir?

Eskiden böyle sorunlar oluyordu. Ama şimdi hangileri olduğunu hatırlamıyorum.

Genel olarak, buna alışkınım.

Genellikle, elbette, hiçbir fark yoktur, en azından benim örneğimde yerleri değiştirmeye çalıştım, her şey çalıştı ...

 
Interesting :

Eskiden böyle sorunlar oluyordu. Ama şimdi hangileri olduğunu hatırlamıyorum.

Tamam yine de not alacağım.