Struct'larda Fonksiyon İşaretçileri
Coddy'nin C Journey'sinin Object Oriented Programming bölümünün bir parçası — ders 38 / 61.
Şimdiye kadar, fonksiyon işaretçilerini bağımsız değişkenler olarak kullandık veya onları argüman olarak geçirdik. Polimorfizme doğru bir sonraki adım, bir fonksiyon işaretçisini doğrudan bir struct içine yerleştirmektir — bu da struct'a kendi davranışını kazandırır.
Bir struct bir fonksiyon göstericisi (function pointer) içerdiğinde, her bir örnek farklı bir fonksiyonu tutabilir. Bu, aynı türdeki iki nesnenin, fonksiyon göstericilerini çağırdığınızda farklı davranabileceği anlamına gelir:
typedef void (*PrintFunc)(const char*);
typedef struct {
const char* name;
PrintFunc print; // Üye olarak fonksiyon göstericisi
} Printer;Printer yapısı artık iki üyeye sahiptir: veri (name) ve davranış (print). Bunu kullanmak için, başlatma sırasında işaretçiye bir fonksiyon atarsınız:
void loud_print(const char* msg) {
printf("!!! %s !!!\n", msg);
}
int main() {
Printer p;
p.name = "Alert";
p.print = loud_print;
p.print("Hello"); // Çıktı: !!! Hello !!!
return 0;
}Fonksiyonu struct üzerinden nasıl çağırdığımıza dikkat edin: p.print("Hello"). Bu, diğer dillerdeki bir nesne üzerinde metot çağırmaya oldukça benzer. Struct, hem verilerini hem de bu veriler üzerinde işlem yapan fonksiyonu taşır.
Bu desen, C'deki polimorfizmin temelidir — farklı örneklere farklı fonksiyonlar atanabilir ve böylece aynı struct türünden farklı davranışlar üretilmesi sağlanır.
Görev
KolayStruct'ların fonksiyon göstericileri (function pointers) aracılığıyla kendi davranışlarını nasıl taşıyabildiğini gösteren bir Notifier sistemi oluşturalım.
Kodunuzu düzenlemek için iki dosya oluşturacaksınız:
notifier.h: Birconst char*parametresi alan ve hiçbir şey döndürmeyenNotifyFuncadında bir fonksiyon göstericisi türü tanımlayın. Ardından, birname(birconst char*) veNotifyFunctüründe birnotifyfonksiyon göstericisi içeren birNotifierstruct'ı tanımlayın.main.c: Başlık dosyanızı dahil edin ve iki bildirim fonksiyonu uygulayın:alert_notify— mesajı şu formatta yazdırır:[ALERT] messageinfo_notify— mesajı şu formatta yazdırır:[INFO] message
Notifierörneği oluşturun, girişe göre uygun fonksiyonu bağlayın ve bildirimi struct'ın fonksiyon göstericisi üzerinden çağırın.
Programınız iki giriş alacaktır: bir bildirim türü (alert için 1, info için 2) ve görüntülenecek bir mesaj.
Türe bağlı olarak, ilgili fonksiyonu notifier'ınızın notify üyesine atayın, ardından mesajı görüntülemek için struct üzerinden çağırın.
Tür 1 ve mesaj "System starting" olduğunda örnek çıktı:
[ALERT] System startingTür 2 ve mesaj "All systems normal" olduğunda örnek çıktı:
[INFO] All systems normalBaşlık dosyanızda include guard kullanmayı ve fonksiyonu struct üyesi üzerinden çağırmayı unutmayın: n.notify(message)
Kendin dene
#include <stdio.h>
#include "notifier.h"
// TODO: alert_notify fonksiyonunu uygula
// Şunu yazdırmalı: [ALERT] message
// TODO: info_notify fonksiyonunu uygula
// Şunu yazdırmalı: [INFO] message
int main() {
int type;
char message[256];
// Girdiyi oku
scanf("%d", &type);
getchar(); // yeni satır karakterini tüket
fgets(message, sizeof(message), stdin);
// Eğer varsa, message sonundaki yeni satır karakterini kaldır
int len = 0;
while (message[len] != '\0') len++;
if (len > 0 && message[len-1] == '\n') message[len-1] = '\0';
// TODO: Bir Notifier örneği oluştur
// TODO: type değerine göre (alert için 1, info için 2),
// notifier'ın notify üyesine uygun fonksiyonu ata
// TODO: struct'ın fonksiyon göstericisi aracılığıyla bildirimi çağır
// Kullanım: n.notify(message)
return 0;
}
Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Object Oriented Programming bölümündeki tüm dersler
1Modüler Programlama Temelleri
Başlık DosyalarıInclude Guard'larKaynak DosyalarıStatik FonksiyonlarÖzet: Modüler Hesap Makinesi4Kapsülleme
Opaque Pointer KavramıOpaque Struct TanımlamaGetter ve Setter MetotlarıSetter Metotlarında DoğrulamaÖzet: Gizli Kutu2Nesneler ve Metotlar
Nesne Olarak Struct'lar'Self' İşaretçisiConst Doğruluğuİşaretçi vs DeğerYardımcı MetotlarÖzet: Point Manager5Proje: Basit Banka Hesabı
Proje KurulumuHesabın Oluşturulması8Polimorfizm
Struct'larda Fonksiyon İşaretçileriMetotları Simüle EtmeArayüz KavramıArayüzleri UygulamaPolimorfik İterasyonÖzet: Greeter3Nesne Yaşam Döngüsü
Constructor DeseniDestructor DeseniStack İlklendirmeDerin KopyalamaÖzet: String Wrapper6Kompozisyon Yoluyla Kalıtım
Struct Gömmeİlk Üye KuralıÜst Üyelere ErişimUpcastingÖzet: Şekil Hiyerarşisi