Fonksiyon Aşırı Yükleme
Coddy'nin C++ Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası — ders 57 / 104.
Fonksiyon aşırı yüklemesi (Function overloading), aynı isme fakat farklı parametre listelerine sahip birden fazla fonksiyon tanımlamanıza olanak tanır. Derleyici, geçirdiğiniz argümanlara göre doğru sürümü seçer. Bu, derleme zamanı polimorfizminin (compile-time polymorphism) temel bir formudur.
Aşırı yüklemenin çalışması için fonksiyonların imzalarının (signature) farklı olması gerekir - parametre sayısı, türleri veya her ikisi:
class Calculator {
public:
int add(int a, int b) {
return a + b;
}
double add(double a, double b) {
return a + b;
}
int add(int a, int b, int c) {
return a + b + c;
}
};
Calculator calc;
calc.add(5, 3); // add(int, int) fonksiyonunu çağırır
calc.add(2.5, 3.7); // add(double, double) fonksiyonunu çağırır
calc.add(1, 2, 3); // add(int, int, int) fonksiyonunu çağırırDerleyici her çağrıyı inceler ve onu uygun aşırı yükleme (overload) ile eşleştirir. Bu tamamen derleme zamanında gerçekleşir, bu nedenle çalışma zamanı ek yükü (runtime overhead) oluşmaz.
Önemli: Yalnızca dönüş türü, aşırı yüklenmiş (overloaded) fonksiyonları ayırt etmez. Aşağıdaki durum bir derleyici hatasına neden olur:
int getValue();
double getValue(); // Hata: yalnızca dönüş türüne göre aşırı yükleme yapılamazFonksiyon aşırı yükleme (function overloading), kodunuzu daha sezgisel hale getirir. addInts, addDoubles ve addThreeInts gibi ayrı isimler oluşturmak yerine, tek bir anlamlı isim kullanırsınız ve geri kalanını derleyicinin halletmesine izin verirsiniz.
Görev
KolayFonksiyon aşırı yüklemesinin (function overloading) gücünü gösteren bir mesaj formatlayıcı sınıfı oluşturalım. Farklı girdi türlerini işleyen birden fazla format() metoduna sahip bir Formatter sınıfı oluşturacaksınız; böylece derleyici, geçirdiğiniz argümanlara göre doğru sürümü seçecektir.
Kodunuzu iki dosya halinde düzenleyeceksiniz:
Formatter.h: Farklı senaryoları işleyen aşırı yüklenmişformat()metodlarına sahip birFormattersınıfı tanımlayın:- Tek bir
std::stringalan ve şunu yazdıran bir metod:Message: <text> - Bir
std::stringve birintöncelik seviyesi alan ve şunu yazdıran bir metod:[Priority <priority>] <text> - Bir
std::stringve birdoublezaman damgası alan ve şunu yazdıran bir metod:[<timestamp>s] <text> - Üç
std::stringparametresi (gönderici, alıcı, mesaj) alan ve şunu yazdıran bir metod:From <sender> to <receiver>: <message>
format()olarak adlandırılmalıdır — derleyici, argümanlara göre doğru olanı seçecektir.- Tek bir
main.cpp: Dört girdi okuyun (her biri ayrı bir satırda):- Basit bir mesaj metni
- Bir öncelik seviyesi (tam sayı)
- Bir zaman damgası (double)
- Bir gönderici adı
Bir
Formatternesnesi oluşturun ve dört aşırı yüklenmiş metodun tümünü gösterin:- Sadece mesaj metni ile
format()metodunu çağırın - Mesaj metni ve öncelik ile
format()metodunu çağırın - Mesaj metni ve zaman damgası ile
format()metodunu çağırın - Gönderici, alıcı olarak "Admin" ve mesaj metni ile
format()metodunu çağırın
Örneğin, System ready, 3, 12.5 ve Server girdileriyle:
Message: System ready
[Priority 3] System ready
[12.5s] System ready
From Server to Admin: System readyAynı metod adı olan format()'ı dört kez nasıl çağırdığınıza, ancak her çağrının argüman türlerine ve sayısına göre farklı bir sürümü nasıl tetiklediğine dikkat edin. Bu, iş başındaki derleme zamanı polimorfizmidir (compile-time polymorphism) — derleyici, program henüz çalışmadan önce hangi aşırı yüklemenin kullanılacağını belirler.
Kopya kağıdı
Fonksiyon aşırı yükleme (function overloading), aynı isme fakat farklı parametre listelerine sahip birden fazla fonksiyon tanımlamanıza olanak tanır. Derleyici, derleme zamanında iletilen argümanlara göre doğru sürümü seçer.
Fonksiyonların imzaları (signature) farklı olmalıdır - parametre sayısı, türleri veya her ikisi birden:
class Calculator {
public:
int add(int a, int b) {
return a + b;
}
double add(double a, double b) {
return a + b;
}
int add(int a, int b, int c) {
return a + b + c;
}
};
Calculator calc;
calc.add(5, 3); // add(int, int) fonksiyonunu çağırır
calc.add(2.5, 3.7); // add(double, double) fonksiyonunu çağırır
calc.add(1, 2, 3); // add(int, int, int) fonksiyonunu çağırırÖnemli: Yalnızca dönüş türü, aşırı yüklenmiş fonksiyonları ayırt etmek için yeterli değildir:
int getValue();
double getValue(); // Hata: yalnızca dönüş türüne göre aşırı yükleme yapılamazFonksiyon aşırı yükleme, çalışma zamanı ek yükü (overhead) getirmeyen bir derleme zamanı polimorfizm (çok biçimlilik) biçimidir.
Kendin dene
#include <iostream>
#include <string>
#include "Formatter.h"
using namespace std;
int main() {
// Girdileri oku
string message;
getline(cin, message);
int priority;
cin >> priority;
double timestamp;
cin >> timestamp;
cin.ignore();
string sender;
getline(cin, sender);
// TODO: Bir Formatter nesnesi oluşturun
// TODO: format() fonksiyonunu sadece message metni ile çağırın
// TODO: format() fonksiyonunu message metni ve priority ile çağırın
// TODO: format() fonksiyonunu message metni ve timestamp ile çağırın
// TODO: format() fonksiyonunu sender, alıcı olarak "Admin" ve message metni ile çağırın
return 0;
}
Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Nesne Yönelimli Programlama bölümündeki tüm dersler
1OOP Temelleri
Harici DosyalarC++ Build ve DerlemeBaşlık Dosyaları ve Kaynak DosyalarıAd Alanları ve KapsamC++'ta OOP'ye GirişSınıflar ve Nesneler'this' İşaretçisiMetotlar (Üye Fonksiyonlar)Öznitelikler (Veri Üyeleri)Ctor ve Dtor TemelleriÖzet - Basit Hesap Makinesi4Sınıf Özellikleri
Örnek ve Statik ÜyelerGetter ve Setter MetotlarıConst Üye FonksiyonlarMutable Anahtar KelimesiStatik Metotlar ve DeğişkenlerFriend Fonksiyonlar ve SınıflarÖzet - Banka Hesabı Yöneticisi7Kalıtım
Temel KalıtımKalıtım Erişim SeviyeleriCtor ve Dtor Çağrılma SırasıMetot Geçersiz KılmaSanal Fonksiyonlar ve VTableÇoklu KalıtımSanal KalıtımÖzet - Çalışan Hiyerarşisi10STL Genel Bakış
STL Genel Bakış ve FelsefesiSTL KonteynerleriİteratörlerSTL AlgoritmalarıFunctor'lar ve Lambda İfadeleriÖzet - Kelime Frekansı13Tasarım Kalıpları 1. Bölüm
Tasarım Kalıplarına GirişSingleton KalıbıFactory ve Abstract FactoryBuilder KalıbıObserver KalıbıStrategy Kalıbı2Bellek Yönetimi
Stack ve Heap Bellekİşaretçiler ve ReferanslarDinamik Bellek (new/delete)C++'ta Akıllı İşaretçilerC++'ta RAIIÖzet - Dinamik Dizi Yöneticisi5Kapsülleme
C++'da Erişim BelirleyicilerDerinlemesine Erişim BelirleyicilerBilgi GizlemeStruct vs Classİç İçe ve Dahili SınıflarÖzet - Öğrenci Kayıt Sistemi8Çok Biçimlilik
Derleme ve Çalışma Zamanı Çok BiçimliliğiFonksiyon Aşırı YüklemeSanal Fonksiyonlara Yeniden BakışSaf Sanal FonksiyonlarSoyut SınıflarC++'ta Arayüz TasarımıDynamic Casting ve RTTIÖzet - Şekil Hesaplayıcı3Yapıcılar ve Yıkıcılar
Varsayılan YapıcıParametreli YapıcıKopya YapıcıTaşıma YapıcısıYapıcı İlklendirme ListeleriTemsilci YapıcılarYıkıcılara Derinlemesine BakışÜç / Beş / Sıfır KuralıÖzet - String Sınıfı6Operatör Aşırı Yükleme
Operatör Aşırı Yüklemeye GirişAritmetik Operatör Aşırı YüklemeKarşılaştırma Operatörü Aşırı YüklemeStream OperatörleriAtama Operatörü Aşırı Yükleme[] ve () Operatör Aşırı YüklemeTip Dönüşüm OperatörleriÖzet - Matris Sınıfı9Şablonlar
Fonksiyon ŞablonlarıSınıf ŞablonlarıŞablon ÖzelleştirmeVariadic ŞablonlarSFINAE ve Type Traits TemelleriÖzet - Generic Konteyner