Menu
Coddy logo textTech

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.

challenge icon

Görev

Kolay

Aynı 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ürmeyen SpeakFunc adında bir fonksiyon göstericisi (function pointer) türü tanımlayın. Ardından, bir name (bir const char*) ve SpeakFunc türünde bir speak fonksiyon göstericisi içeren bir Speaker struct'ı tanımlayın.
  • main.c: Başlık dosyanızı dahil edin ve üç farklı konuşma fonksiyonu uygulayın:
    • barkWoof! yazdırır
    • meowMeow! yazdırır
    • chirpChirp! yazdırır
    Ardından, girişe bağlı olarak her biri farklı bir fonksiyona bağlanmış iki Speaker örneği oluşturun ve polimorfik davranışı iş başında görmek için bunların speak metotları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;
}
quiz iconKendini test et

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