Aydoğan Emsiz  
Yazılım Mühendisi  
Aktif Mühendislik

Özet — Programlama dillerinde çok sık kullandığımız operatörler standart tiplerde farklı veriler için işlem yapmamızı sağlar. Ancak bu standart tipler bazen yazılımcıyı sınırlar ve daha karmaşık kodlar yazmamıza sebep olur. Bu gibi durumlarda “operatörlerin aşırı yüklenmesi (operator overloading)” işlemi bize çözüm sunuyor.

I. GİRİŞ

Operatörler, mantıksal karşılaştırmaların ve aritmetik işlemlerin yapılmasını sağlayan karakterler topluluğunun programlama dilindeki adıdır.

İlkel veri tipleri olarak nitelendirilen integer, double, string, boolean, vb. veri tipleri ile işlem yapmak için operatörler (+ - / * < > <= >= == != & && | || vb.) kullanılırız.

Derleyiciler bu ilkel veri tiplerini tanır ve işlemler yapmamıza izin verir. Ancak kendi veri tiplerimizi oluşturur ve onlar üzerinde bu operatörleri kullanmak istersek derleyici buna izin vermez ve “+ operatörü bu tipte işlem yapamaz.” uyarısı verir.

Bu durumda ilgili operatörlere kendi veri tipimizi tanıtır ve onlara yeni anlamlar kazandırabiliriz. Yapacağımız bu işleme “Operatörlerin aşırı yüklenmesi (Operator overloading)” deriz. Aşağıdaki örneklerle bu anlatımı biraz da kodlarla anlamaya çalışalım.

II. ÖRNEKLER

Aşağıdaki örneklerde ilkel tiplerde operatör kullanımlarını daha iyi anlayabiliriz;

//Integer tipinde iki verinin matematiksel toplamı aşağıdaki gibidir;  
int a = 5;  
int b = 3;  
int c = a + b; //c’nin sonucu 8 olur.  
//String tipinde iki verinin metinsel toplamı aşağıdaki gibidir;  
string ad = "Aydoğan";  
string soyad = " Emsiz";  
string tamAd = ad + soyad; // tamAd değeri "Aydoğan Emsiz" olur.  

//Boolean tipinde iki verinin mantıksal karşılaştırması aşağıdaki gibidir;  
bool f = true;  
bool g = false;  
if (f != g)  
{
   //f eşit değildir g'ye;  
}  

Örneklerde görüldüğü gibi “+” operatörü integer ve string tiplerinde, “!=” operatörü ise boolean tipinde veriler için kullanıldı.

İlkel veri tiplerinin dışına çıkıp oluşturacağımız kendi veri tiplerimiz için operatörleri nasıl kullanacağımızı yani operatörlerin aşırı yüklenmesi işlemini aşağıdaki C# konsol uygulaması olarak hazırlanmış örnek ile detaylı bir şekilde inceleyelim[1];

//Kutu adında bir nesne(veri tipi) oluşturuyoruz. 
class Kutu
{
    private double uzunluk; // Kutunun uzunluğu 
    private double genislik; // Kutunun genişliği 
    private double yukseklik; // Kutunun yüksekliği 

    //Kutunun hacmini hesaplıyoruz.
    public double getirHacim()
    {
        return uzunluk * genislik * yukseklik;
    }

    //Kutunun uzunluğunu ayarlıyoruz. 
    public void ayarlaUzunluk(double _uzunluk)
    {
        uzunluk = _uzunluk;
    }

    //Kutunun genişliğini ayarlıyoruz. 
    public void ayarlaGenislik(double _genislik)
    {
        genislik = _genislik;
    }

    //Kutunun yüksekliğini ayarlıyoruz. 
    public void ayarlaYukseklik(double _yukseklik)
    {
        yukseklik = _yukseklik;
    }

    // İki Kutu nesnesini toplamak için "+" operatörüne yaptığımız aşırı yükleme metodu. 
    public static Kutu operator +(Kutu b, Kutu c)
    {
        Kutu kutu = new Kutu();
        kutu.uzunluk = b.uzunluk + c.uzunluk;
        kutu.genislik = b.genislik + c.genislik;
        kutu.yukseklik = b.yukseklik + c.yukseklik;
        return kutu;
    }

    // İki Kutu nesnesinin eşitliğini karşılaştırmak için "==" operatörüne yaptığımız aşırı yükleme metodu. 
    public static bool operator ==(Kutu birinciKutu, Kutu ikinciKutu)
    {
        bool durum = false;

        if (birinciKutu.uzunluk == ikinciKutu.uzunluk && birinciKutu.yukseklik == ikinciKutu.yukseklik && birinciKutu.genislik == ikinciKutu.genislik)
        {
            durum = true;
        }
        return durum;
    }

    // İki Kutu nesnesinin eşitsizliğini karşılaştırmak için "!=" operatörüne yaptığımız aşırı yükleme metodu. 
    public static bool operator !=(Kutu birinciKutu, Kutu ikinciKutu)
    {
        bool durum = false;

        if (birinciKutu.uzunluk != ikinciKutu.uzunluk || birinciKutu.yukseklik != ikinciKutu.yukseklik || birinciKutu.genislik != ikinciKutu.genislik)
        {
            durum = true;
        }
        return durum;
    }

    // İki Kutu nesnesinin küçüklüğünü karşılaştırmak için "<" operatörüne yaptığımız aşırı yükleme metodu. 
    public static bool operator <(Kutu birinciKutu, Kutu ikinciKutu)
    {
        bool durum = false;

        if (birinciKutu.uzunluk < ikinciKutu.uzunluk && birinciKutu.yukseklik < ikinciKutu.yukseklik && birinciKutu.genislik < ikinciKutu.genislik)
        {
            durum = true;
        }
        return durum;
    }

    // İki Kutu nesnesinin büyüklüğünü karşılaştırmak için ">" operatörüne yaptığımız aşırı yükleme metodu. 
    public static bool operator >(Kutu birinciKutu, Kutu ikinciKutu)
    {
        bool durum = false;
        if (birinciKutu.uzunluk > ikinciKutu.uzunluk && birinciKutu.yukseklik > ikinciKutu.yukseklik && birinciKutu.genislik > ikinciKutu.genislik)
        {
            durum = true;
        }
        return durum;
    }

    // İki Kutu nesnesinin küçük eşitliğini karşılaştırmak için "<=" operatörüne yaptığımız aşırı yükleme metodu. 
    public static bool operator <=(Kutu birinciKutu, Kutu ikinciKutu)
    {
        bool durum = false;

        if (birinciKutu.uzunluk <= ikinciKutu.uzunluk && birinciKutu.yukseklik <= ikinciKutu.yukseklik && birinciKutu.genislik <= ikinciKutu.genislik)
        {
            durum = true;
        }
        return durum;
    }

    // İki Kutu nesnesinin büyük eşitliğini karşılaştırmak için ">=" operatörüne yaptığımız aşırı yükleme metodu. 
    public static bool operator >=(Kutu birinciKutu, Kutu ikinciKutu)
    {
        bool durum = false;

        if (birinciKutu.uzunluk >= ikinciKutu.uzunluk && birinciKutu.yukseklik >= ikinciKutu.yukseklik && birinciKutu.genislik >= ikinciKutu.genislik)
        {
            durum = true;
        }
        return durum;
    }
}

class Test
{

    static void Main(string[] args)
    {
        Kutu Kutu1 = new Kutu(); // Kutu1 adında bir Kutu nesnesi oluşturduk. 
        Kutu Kutu2 = new Kutu(); // Kutu2 adında bir Kutu nesnesi oluşturduk. 
        Kutu Kutu3 = new Kutu(); // Kutu3 adında bir Kutu nesnesi oluşturduk. 
        Kutu Kutu4 = new Kutu();
        double hacim = 0.0; // Kutunun varsayılan hacmini tanımladık. 

        // Kutu1'in uzunluğunu, genişliğini ve yükseliğini ayarlıyoruz. 
        Kutu1.ayarlaUzunluk(6.0);
        Kutu1.ayarlaGenislik(7.0);
        Kutu1.ayarlaYukseklik(5.0);

        // Kutu2'nin uzunluğunu, genişliğini ve yükseliğini ayarlıyoruz. 
        Kutu2.ayarlaUzunluk(12.0);
        Kutu2.ayarlaGenislik(13.0);
        Kutu2.ayarlaYukseklik(10.0);

        // Kutu1'in hacmini yazdırıyoruz. 
        hacim = Kutu1.getirHacim();
        Console.WriteLine("Kutu1'in hacmi : {0}", hacim);
        // Kutu2'nin hacmini yazdırıyoruz. 
        hacim = Kutu2.getirHacim();
        Console.WriteLine("Kutu2'nin hacmi : {0}", hacim);


        // Kutu3'ün hacmini yazdırıyoruz. 
        Kutu3 = Kutu1 + Kutu2; // Aşırı yükleme operatörümüz ile Kutu3'ün uzunluk, genişlik ve yüksekliği, Kutu1 ve Kutu2'nin toplamları olarak tanımlandık. 
        hacim = Kutu3.getirHacim();
        Console.WriteLine("Kutu3'ün hacmi : {0}", hacim);

        //Kutuları karşılaştırıyoruz. 
        if (Kutu1 > Kutu2)
            Console.WriteLine("Kutu1 büyüktür Kutu2'den");
        else
            Console.WriteLine("Kutu1 büyüktür değildir Kutu2'den");

        if (Kutu1 < Kutu2)
            Console.WriteLine("Kutu1 küçüktür Kutu2'den");
        else
            Console.WriteLine("Kutu1 küçük değildir Kutu2'den");

        if (Kutu1 >= Kutu2)
            Console.WriteLine("Kutu1 büyük veya eşittir Kutu2'ye");
        else
            Console.WriteLine("Kutu1 büyük veya eşit değildir Kutu2'ye");

        if (Kutu1 <= Kutu2)
            Console.WriteLine("Kutu1 küçük veya eşittir Kutu2'ye");
        else
            Console.WriteLine("Kutu1 küçük veya eşit değildir Kutu2'ye");

        if (Kutu1 != Kutu2)
            Console.WriteLine("Kutu1 eşit değildir Kutu2'ye");
        else
            Console.WriteLine("Kutu1 eşittir Kutu2'ye");

        Kutu4 = Kutu3; //Kutu4'e Kutu3'ün değerlerini atadık. 

        if (Kutu3 == Kutu4)
            Console.WriteLine("Kutu3 eşittir Kutu4'e");
        else
            Console.WriteLine("Kutu3 eşit değildir Kutu4'e");

        Console.ReadKey();
    }
}

Uygulama Çıktısı


Kutu1'in hacmi : 210  
Kutu2'nin hacmi : 1560 
Kutu3'ün hacmi : 5400
Kutu1 büyüktür değildir Kutu2'den  
Kutu1 küçüktür Kutu2'den  
Kutu1 büyük veya eşit değildir Kutu2'ye  
Kutu1 küçük veya eşittir Kutu2'ye  
Kutu1 eşit değildir Kutu2'ye  
Kutu3 eşittir Kutu4'e  


III. AŞIRI YÜKLEME YAPILABİLEN VE YAPILAMAYAN OPERATÖRLER

Aşağıdaki tabloda aşırı yükleme yapılabilen veya yapılamayan operatörler listesini inceleyebiliriz[1].

# Operatörler Açıklama
1 +, -, !, ~, ++, -- Tekli (Unary) operatörler bir işlenen (operand) alarak aşırı yüklenebilir.
2 +, -, *, /, % İkili (Binary) operatörler bir işlenen (operand) alarak aşırı yüklenebilir.
3 ==, !=, <, >, <=, >= Karşılaştırma operatörleri aşırı yüklenebilir.
4 &&, || Koşullu mantıksal operatörler doğrudan aşırı yüklenemez.
5 +=, -=, *=, /=, %= Atama operatörleri aşırı yüklenemez.
6 =, ., ?:, ->, new, is, sizeof, typeof Bu operatörler aşırı yüklenemezler..

Operatörleri daha kapsamlı incelemek için wikibooks.org web sitesinde yer alan “C Sharp Programlama Dili/Operatörler” sayfasını ziyaret edebilirsiniz[2].

REFERANSLAR

Paylaş: