C++ Operatörlerin Aşırı Yüklenmesi

Operatörleri aşırı yüklemek, operatörleri yeniden tanımlamamıza imkan sağlar. Sınıf yapıları sayesinde kullanıcı tanımlı türler oluşturabiliyoruz. Bu türleri operatörle kullanabilmek için operatörleri aşırı yüklemeliyiz. int veri tipini düşünün. int türünde bir değişken tanımladık ve bu değişkene değer atadık, bu değişken üzerinde arttırma, azaltma, toplama, çıkarma, ekrana yazdırma gibi işlemler yaptık. Bu işlemleri yaparken operatörleri kullanmak zorundayız. Ancak kullanıcının kendi tanımladığı türde bu işlemleri operatör ile yapmak için operatörler aşırı yüklenmelidir. Şimdi daha iyi anlamak için bir örnek yapalım. Sayi adlı bir sınıfımız olsun ve bu sınıftan s1 ile s2 isimli iki nesne oluşturalım. Bu nesnelerin sayısal değerlere sahip olduğunu varsayalım. Bu nesne değişkenlerin sahip olduğu değerleri birbiriyle toplayıp, üçüncü olarak tanımlanan sonuç adlı nesneye atayalım.
#include <iostream>

using namespace std;

class Sayi{
    public:
        Sayi(int sayi = 0) :veri(sayi){};
        // '+' operatörü aşırı yüklendi.
        Sayi operator+(const Sayi& nesne);
        void goster() const;
    private:
        int veri;
};

Sayi Sayi::operator+(const Sayi& nesne){
    int sonuc;
    sonuc = veri + nesne.veri;
    return sonuc; 
}

void Sayi::goster() const{
    cout << veri << endl;
}

int main(){
    Sayi s1(11);
    Sayi s2(22);
    Sayi sonuc;

    sonuc = s1 + s2;

    sonuc.goster();
}
Operatör fonksiyonu ile + operatörü aşırı yüklenmiş oldu. Operator fonksiyonlar ile normal fonksiyonlar arasında aslında bir fark yoktur. İsimlendirme olarak operator anahtar kelimesi ve operatör simgesi kullanılıyor. Operatör simgesine karşılık gelen durumlarda operatör fonksiyonu çağırılmaktadır. Burada + operatorüne çıkartma, çarpma, bölme gibi çok farklı işlem özellikleri verebilirdik.

Operatör fonkiyonu global olarak tanımlanmak istenirse, Sayi sınıfına friend olarak bildirilir. Aşağıdaki kodda olduğu gibi:
#include <iostream>

using namespace std;

class Sayi{
    public:
        Sayi(int sayi = 0) :veri(sayi){};
        void goster() const;
    private:
        int veri;

    friend Sayi operator+(const Sayi &, const Sayi &);
};

Sayi operator+(const Sayi &s1, const Sayi &s2){
    int sonuc = s1.veri + s2.veri;
    return Sayi(sonuc);
}

void Sayi::goster() const{
    cout << veri << endl;
}

int main(){
    Sayi s1(11);
    Sayi s2(22);
    Sayi sonuc;

    sonuc = s1 + s2;

    sonuc.goster();
}
friend olarak bildirmemizin sebebi metodun Sayi sınıfına ait private verilerine erişebilmesi içindir.
Bazı Operatörler Aşırı Yüklenemez
Çoğu operatörü aşırı yükleyebiliriz, ancak .(nokta) :: ?: sizeof operatörleri bunların dışındadır.

IO Operatörlerin Aşırı Yüklenmesi (<<,>>)

Bu başlık altında ise yukarıdaki örneği devam ettirerek input(>>) ve output(<<) operatörlerini aşırı yükleyeceğiz. Yukarıda veri girişini s1(11) şeklinde ve veri çıkışını sonuc.goster() şeklinde yapmıştık.
friend ostream &operator<<(ostream &out, Sayi nesne){
    out << nesne.veri;
    return out;
}

friend istream &operator>>(istream &in, Sayi &nesne){
    in >> nesne.veri;
    return in;
}
Yukarıdaki kodu Sayi sınıfı içerisinde yazıyoruz. Daha sonrasında main fonksiyonunda aşağıdaki gibi << ve >> operatörlerini kullanabiliriz.
int main(){
    Sayi s1;
    Sayi s2;
    Sayi sonuc;

    cin >> s1;
    cin >> s2;

    sonuc = s1 + s2;

    cout << sonuc;
}
Diğer operatörlerin aşırı yüklenmesini buradaki bağlantıdan bulup, inceleyebilirsiniz.

Hiç yorum yok:

Yorum Gönderme