Constructor Deseni
Coddy'nin C Journey'sinin Object Oriented Programming bölümünün bir parçası — ders 12 / 61.
Java veya C++ gibi dillerde, nesneleri belleği otomatik olarak tahsis eden ve alanları ilklendiren özel fonksiyonlar olan kurucuları (constructors) kullanarak oluşturursunuz. C'de böyle bir özellik yoktur, ancak bunu basit bir desenle simüle edebiliriz: bir create_ fonksiyonu.
C'deki bir yapıcı (constructor) fonksiyonu genellikle üç şey yapar: malloc ile bellek ayırır, tüm alanları uygun değerlere başlatır ve yeni nesneye bir işaretçi (pointer) döndürür:
typedef struct {
char *name;
int age;
} Person;
Person *create_person(const char *name, int age) {
Person *p = malloc(sizeof(Person));
p->name = malloc(strlen(name) + 1);
strcpy(p->name, name);
p->age = age;
return p;
}
Fonksiyon bir işaretçi döndürür çünkü nesne yığında (stack) değil, öbekte (heap) bulunur. Bu, fonksiyon döndükten sonra da nesnenin kalıcı olduğu ve serbestçe paylaşılabileceği anlamına gelir. Çağıran taraf bunu şu şekilde kullanır:
Person *alice = create_person("Alice", 30);
printf("%s is %d years old\n", alice->name, alice->age);
Yapıcının (constructor) tüm karmaşık detayları —yapıyı (struct) tahsis etme, dize (string) için yer ayırma ve veriyi kopyalama— nasıl hallettiğine dikkat edin. Çağıran taraf sadece başlangıç değerlerini sağlar ve kullanıma hazır bir nesne alır. Bu, oluşturma mantığını tek bir yerde kapsüller, kodunuzu daha temiz ve hataya daha az eğilimli hale getirir.
Görev
KolayYığın (heap) üzerinde kitap nesneleri oluşturmak için yapıcı (constructor) desenini kullanan bir Book modülü oluşturalım. Tüm bellek tahsisini ve başlatma işlemlerini gerçekleştiren ve kullanıma hazır bir işaretçi döndüren bir create_ fonksiyonu yazma pratiği yapacaksınız.
Üç dosya oluşturacaksınız:
book.h: İki üyeye sahip birBookyapısı (struct) bildirin:char *title(dinamik olarak tahsis edilmiş bir dizeye işaretçi) veint pages. Ayrıca, bir başlık dizesi ve sayfa sayısı alan, ardından yeni oluşturulan bir Book'a işaretçi döndüren bircreate_bookyapıcı fonksiyonu bildirin.BOOK_Hsembolü ile include guard kullanın.book.c:create_bookfonksiyonunu uygulayın. Yapıcınız, Book yapısının kendisi için bellek tahsis etmeli, ardından başlık dizesi için ayrı bir bellek tahsis etmeli (null sonlandırıcıyı hesaba katmayı unutmayın), başlığı yeni belleğe kopyalamalı, sayfa alanını ayarlamalı ve yeni Book'a olan işaretçiyi döndürmelidir.main.c: Bir kitap oluşturmak ve bilgilerini görüntülemek için yapıcınızı kullanın.
İki girdi alacaksınız: kitap başlığı (bir dize) ve sayfa sayısı (bir tam sayı).
Ana dosyanızda, sağlanan değerlerle yeni bir kitap oluşturmak için create_book fonksiyonunu kullanın, ardından bilgilerini şu formatta yazdırın:
Title: {title}
Pages: {pages}Örneğin, The C Programming Language ve 272 girdileriyle çıktı şöyle olacaktır:
Title: The C Programming Language
Pages: 272Yapıcınızın tüm oluşturma mantığını kapsadığını unutmayın; çağıran taraf yalnızca başlangıç değerlerini sağlar ve kullanıma hazır, tam olarak başlatılmış bir nesne alır.
Kopya kağıdı
C'deki bir yapıcı (constructor) fonksiyonu, bellek ayırarak ve alanları başlatarak nesne oluşturmayı simüle eder. Genellikle create_ adlandırma modelini takip eder.
Bir yapıcı fonksiyon üç şey yapar:
mallocile bellek ayırır- Tüm alanları uygun değerlerle başlatır
- Yeni nesneye bir işaretçi (pointer) döndürür
Örnek yapıcı deseni:
typedef struct {
char *name;
int age;
} Person;
Person *create_person(const char *name, int age) {
Person *p = malloc(sizeof(Person));
p->name = malloc(strlen(name) + 1);
strcpy(p->name, name);
p->age = age;
return p;
}
Yapıcıyı kullanma:
Person *alice = create_person("Alice", 30);
printf("%s is %d years old\n", alice->name, alice->age);
Fonksiyon bir işaretçi döndürür çünkü nesne yığında (heap) yaşar ve fonksiyon döndükten sonra da varlığını sürdürür. Bu, oluşturma mantığını tek bir yerde kapsüller, kodu daha temiz ve hataya daha az açık hale getirir.
Kendin dene
#include <stdio.h>
#include <stdlib.h>
#include "book.h"
int main() {
char title[256];
int pages;
// Girdiyi oku
fgets(title, sizeof(title), stdin);
// Eğer varsa yeni satır karakterini kaldır
for (int i = 0; title[i]; i++) {
if (title[i] == '\n') {
title[i] = '\0';
break;
}
}
scanf("%d", &pages);
// TODO: Sağlanan değerlerle yeni bir kitap oluşturmak için create_book işlevini kullanın
// TODO: Kitap bilgilerini istenen formatta yazdırın:
// Title: {title}
// Pages: {pages}
// TODO: İşiniz bittiğinde ayrılan belleği serbest bırakmayı unutmayı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ı3Nesne 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