Metotları Simüle Etme
Coddy'nin C Journey'sinin Object Oriented Programming bölümünün bir parçası — ders 39 / 61.
Bir struct içine bir fonksiyon göstericisi yerleştirmeyi gördünüz. Asıl güç, aynı struct türünün farklı örneklerine farklı fonksiyonlar atadığınızda ortaya çıkar; değişken davranışlı metotları bu şekilde simüle ederiz.
Özelleştirilebilir mantığa sahip bir eylemi temsil eden bir yapıyı (struct) düşünün:
typedef void (*ActionFunc)(void);
typedef struct {
const char* name;
ActionFunc execute;
} Action;Örnekler oluştururken, her birine farklı fonksiyonlar bağlarsınız:
void say_hello(void) {
printf("Hello!\n");
}
void say_goodbye(void) {
printf("Goodbye!\n");
}
int main() {
Action greet = { "Greet", say_hello };
Action farewell = { "Farewell", say_goodbye };
greet.execute(); // Çıktı: Hello!
farewell.execute(); // Çıktı: Goodbye!
return 0;
}Hem greet hem de farewell aynı tiptedir (Action), ancak her biri üzerinde execute çağırmak tamamen farklı sonuçlar üretir. Struct sadece veri tutmaz — her örneğe göre değişen davranışlar tutar.
Bu desen, nesnelerin diğer dillerde nasıl çalıştığını yansıtır: aynı arayüzü paylaşsalar bile her nesne bir metodun kendi uygulamasına sahip olabilir.
Görev
KolayAynı struct türündeki farklı örneklerin, içlerine hangi fonksiyonun bağlandığına bağlı olarak nasıl tamamen farklı davranışlar sergileyebileceğini gösteren bir Speaker sistemi kuralım.
Kodunuzu düzenlemek için iki dosya oluşturacaksınız:
speaker.h: Hiçbir parametre almayan ve hiçbir şey döndürmeyenSpeakFuncadında bir fonksiyon göstericisi (function pointer) türü tanımlayın. Ardından, birname(birconst char*) veSpeakFunctüründe birspeakfonksiyon göstericisi içeren birSpeakerstruct'ı tanımlayın.main.c: Başlık dosyanızı dahil edin ve üç farklı konuşma fonksiyonu uygulayın:bark—Woof!yazdırırmeow—Meow!yazdırırchirp—Chirp!yazdırır
Speakerörneği oluşturun ve polimorfik davranışı iş başında görmek için bunlarınspeakmetotlarını çağırın.
Programınız iki girdi alacaktır: birinci hoparlör tipi (bark için 1, meow için 2, chirp için 3) ve ikinci hoparlör tipi (yine 1, 2 veya 3).
İki Speaker örneği oluşturun — onlara istediğiniz ismi verebilirsiniz ("Dog", "Cat", "Bird" veya sadece "Speaker1", "Speaker2" gibi). Her birini giriş koduna göre uygun fonksiyona bağlayın, ardından her örnek üzerinde sırayla speak fonksiyonunu çağırın.
Birinci tip 1 ve ikinci tip 2 olduğunda örnek çıktı:
Woof!
Meow!Birinci tip 3 ve ikinci tip 3 olduğunda örnek çıktı:
Chirp!
Chirp!Buradaki temel içgörü, her iki hoparlörün de aynı Speaker türünde olmasına rağmen, her birinin speak üyesine farklı bir fonksiyon atandığı için farklı çıktılar üretmesidir. Başlık dosyanızda include guard kullanmayı unutmayın.
Kopya kağıdı
Aynı struct türünün farklı örnekleri, farklı fonksiyon işaretçileri tutabilir ve bu da polimorfik (çok biçimli) davranış sergilemelerine olanak tanır.
Bir fonksiyon işaretçisi türü ve bunu kullanan bir struct tanımlayın:
typedef void (*ActionFunc)(void);
typedef struct {
const char* name;
ActionFunc execute;
} Action;Farklı fonksiyonlar atanmış örnekler oluşturun:
void say_hello(void) {
printf("Hello!\n");
}
void say_goodbye(void) {
printf("Goodbye!\n");
}
int main() {
Action greet = { "Greet", say_hello };
Action farewell = { "Farewell", say_goodbye };
greet.execute(); // Output: Hello!
farewell.execute(); // Output: Goodbye!
return 0;
}Her iki örnek de aynı türü paylaşır ancak fonksiyon işaretçileri çağrıldığında farklı davranışlar sergilerler.
Kendin dene
#include <stdio.h>
#include "speaker.h"
// TODO: "Woof!" yazdıran bark fonksiyonunu uygulayın
// TODO: "Meow!" yazdıran meow fonksiyonunu uygulayın
// TODO: "Chirp!" yazdıran chirp fonksiyonunu uygulayın
int main() {
int type1, type2;
scanf("%d", &type1);
scanf("%d", &type2);
// TODO: İki Speaker örneği oluşturun
// TODO: type1 değerine göre ilk hoparlörün speak fonksiyonunu bağlayın
// (1 = bark, 2 = meow, 3 = chirp)
// TODO: type2 değerine göre ikinci hoparlörün speak fonksiyonunu bağlayın
// (1 = bark, 2 = meow, 3 = chirp)
// TODO: Her bir hoparlörde sırasıyla speak fonksiyonunu çağırın
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