Fonksiyonun Aşırı Yüklenmesi

Fonksiyonun ismi çoğu zaman temel amacını yansıtma eğilimi gösterir. Bir kural olarak, okunaklı programlar iyi seçilmiş çeşitli tanımlayıcılar içerir. Bazen farklı fonksiyonların aynı amaçla kullanıldıkları olur. Örneğin, çifte duyarlık sayılarını içeren bir dizinin ortalamasını hesaplayan bir fonksiyonu ve bir de aynı fonksiyonun tamsayı dizileriyle çalışan bir versiyonunu göz önüne getirelim. İkisi de AverageFromArray şeklinde isimlendirilmek için uygundur:

//+------------------------------------------------------------------+
//| double tipi bir dizinin ortalamasının hesaplanması               |
//+------------------------------------------------------------------+
double AverageFromArray(const double & array[],int size)
  {
   if(size<=0) return 0.0;
   double sum=0.0;
   double aver;
//---
   for(int i=0;i<size;i++)
     {
      sum+=array[i];    // double için toplama işlemi
     }
   aver=sum/size;       // Toplamı ortalamaya böldük
//---
   Print("double tipli dizinin ortalamasının hesaplanması");
   return aver;
  }
//+------------------------------------------------------------------+
//| int tipi bir dizinin ortalamasının hesaplanması                  |
//+------------------------------------------------------------------+
double AverageFromArray(const int & array[],int size)
  {
   if(size<=0) return 0.0;
   double aver=0.0;
   int sum=0;
//---
   for(int i=0;i<size;i++)
     {
      sum+=array[i];     // int için toplama işlemi
     }
   aver=(double)sum/size;// double tipli miktarı alıp ve böl
//---
   Print("int tipli dizinin ortalamasının hesaplanması");
   return aver;
  }

İki fonksiyon da Print() fonksiyonuyla verilen çıkış mesajını içermektedir;

   Print("int tipli dizinin ortalamasının hesaplanması");

Derleyici, gereken bir fonksiyonu argümanlarının tiplerine ve sayılarına göre seçer. Bu seçime referans oluşturan kural, imza eşleştirme algoritması olarak adlandırılır. İmza, fonksiyon bildiriminde kullanılan tiplerin bir listesidir.

Örnek:

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//---
   int    a[5]={1,2,3,4,5};
   double b[5]={1.1,2.2,3.3,4.4,5.5};
   double int_aver=AverageFromArray(a,5);
   double double_aver=AverageFromArray(b,5);
   Print("int_aver = ",int_aver,"   double_aver = ",double_aver);
  }
//--- Betiğin sonucu
// int tipli dizinin ortalamasının hesapla
// double tipli dizinin ortalamasının hesapla
// int_aver= 3.00000000    double_aver= 3.30000000

Fonksiyonun aşırı yüklenmesi, aynı isimde ama farklı parametrelerle birkaç fonksiyon oluşturma işlemidir. Bu, fonksiyonun aşırı yüklenmiş versiyonlarında, argümanların ve/veya argüman tiplerinin farklı olmaları gerektiği anlamına gelir. Belirli bir fonksiyon türevi, fonksiyon bildirimindeki parametre listesine karşılık gelen argümanların listesi temel alınarak seçilir.

Aşırı yüklenmiş bir fonksiyon çağrıldığında, derleyicinin uygun fonksiyonu seçmek için bir algoritmaya sahip olması gerekir. Bu seçimi yürüten algoritma mevcut tiplerin dönüşümüne bağlıdır. En iyi örtüşme benzersiz olmalıdır. Aşırı yüklenmiş bir fonksiyonun, tüm diğer türevler arasında, en az bir argüman için en iyi eşleşme olması gerekir. Ayrıca, fonksiyon tüm diğer argümanlar için, diğer türevlerden daha kötü olmayan bir eşleşmeye sahip olmalıdır.

Aşağıda bir eşleştirme algoritması yer almaktadır.

Aşırı Yüklenmiş bir Fonksiyonun Seçiminin Algoritması

  1. Katı eşleşme kullan (eğer mümkünse).
  2. Standart tip artırımını dene.
  3. Standart tip dönüşümünü dene.

Standart tip artırımı diğer standart dönüşümlerden daha iyidir. Artırma float tipinden double tipine, bool, char, short veya enum tiplerinden int tipine yapılan dönüşümdür. Tamsayı tipli benzer dizilerin dönüşümleri de yine tip dönüşümü içerisinde değerlendirilir. Benzer tipler şunlardır: bool, char ve uchar, bu üç tipin hepsi tek-baytlık tamsayılardır. 'short' ve 'ushort' çift-bayt tamsayılar; int, uint ve color; long, ulong ve datetime 4-bayt tamsayılardır.

Elbette en iyisi katı eşleşmedir. Böyle bir tutarlılığı sağlamak için tip dönüşümü kullanılır. Derleyici belirsiz durumlarla başa çıkamaz. Bu yüzden, küçük tip farklılıklarına ve aşırı yüklenmiş fonksiyonu anlaşılmaz kılan gizli dönüşümlere güvenmemelisiniz.

Şüphe durumunda katı uyumu sağlayacak açık dönüşümler kullanın.

Aşırı yüklenmiş fonksiyonun MQL5 içindeki örneği ArrayInitialize() fonksiyonu sayfasında görülebilir.

Fonksiyon aşırı yükleme kuralları sınıf yöntemlerinin aşırı yüklenmesinde de uygulanır

 

Sistem fonksiyonlarının aşırı yüklenmesine izin verilir. Bu yüzden derleyicinin gerekli fonksiyonu doğru seçebildiği gözlenmelidir. Örneğin, MathMax() sistem fonksiyonunu 4 ayrı şekilde aşırı yükleyebiliriz ama bunlardan sadece ikisi doğru olacaktır.

Örnek:

// 1. aşırı yükleme izni var - fonksiyon, parametre sayısı açışından gömülü MathMax() fonksiyonundan ayrılıyor
double MathMax(double a,double b,double c);
 
// 2. aşırı yükleme izni yok!
// parametre sayıları farklı ama sonuncusu bir varsayılan (ön tanımlı) değere sahip
// bu, çağrı sırasında sistem fonksiyonunun gizlenmesine yol açıyor ve bu kabul edilemez
double MathMax(double a,double b,double c=DBL_MIN);
 
// 3. aşırı yükleme izni var - a ve b parametrelerinin tipleri aracılığıyla normal aşırı yükleme
double MathMax(int a,int b);
 
// 4. aşırı yükleme izni yok!
// parametrelerin tipleri ve sayıları orjinal double MathMax(double a,double b) ile aynı
int MathMax(double a,double b);

Ayrıca Bakınız

Aşırı Yükleme, Sanal Fonksiyonlar, Polimorfizm