Jenerik Sarmalayıcı
Coddy'nin C Journey'sinin Object Oriented Programming bölümünün bir parçası. Ders 50 / 61.
Tek başına bir void* her türlü veriyi depolayabilir, ancak kritik bir kusuru vardır: hangi türü tuttuğunu takip edemezsiniz. Gerçekten kullanışlı genel amaçlı kapsayıcılar oluşturmak için veri işaretçisini tür bilgileriyle eşleştirmemiz gerekir. Generic Wrapper deseni işte burada devreye girer.
Fikir basit: bir void* işaretçisini, saklanan türü tanımlayan bir enum ile bir araya getiren bir struct oluşturun. Bu şekilde wrapper, contents değerini nasıl yorumlayacağını her zaman bilir.
typedef enum {
TYPE_INT,
TYPE_STRING
} DataType;
typedef struct {
void* data;
DataType type;
} Wrapper;data depolarken, gerçek değer için memory ayırır ve türünü kaydedersin. Geri alırken, dönüştürmeden önce türü kontrol edersin:
Wrapper wrap_int(int value) {
int* p = malloc(sizeof(int));
*p = value;
return (Wrapper){ .data = p, .type = TYPE_INT };
}
void print_wrapper(Wrapper* w) {
if (w->type == TYPE_INT) {
printf("%d\n", *(int*)w->data);
} else if (w->type == TYPE_STRING) {
printf("%s\n", (char*)w->data);
}
}Bu desen, C'de tür güvenli generic kapsayıcılar oluşturmanın temelidir. enum, bir çalışma zamanı tür etiketi görevi görerek kodunuzun stored data'nın nasıl işleneceği konusunda güvenli kararlar almasını sağlar.
Görev
KolayDaha sonra verileri güvenli bir şekilde alıp yazdırabilmek için hangi türü tuttuğunu izleyen, bir integer veya bir string depolayabilen, tür güvenli bir Generic wrapper system oluşturalım.
kodunu üç dosyada düzenleyeceksin:
wrapper.h:TYPE_INTveTYPE_STRINGdeğerlerine sahip birDataTypeenum tanımla. Ardından birvoid*data pointer'ını birDataTypefield ile bir araya getiren birWrapperstruct tanımla. Wrapper'lar oluşturmak ve içeriklerini yazdırmak için function prototypes bildir.wrapper.c: Wrapper işlevselliğini Implement et:wrap_int: bir integer alır, bunun için memory allocate eder, değeri Store eder ve appropriate type tag'e sahip bir Wrapper döndürürwrap_string: bir string (char*) alır, memory allocate eder ve string'i kopyalar; ardından string type tag'ine sahip bir Wrapper döndürürprint_wrapper: type tag'i Check eder ve data'yı appropriately yazdırır (integer olduğu gibi, string olduğu gibi)free_wrapper: Wrapper içindeki dynamically allocate edilmiş data'yı serbest bırakır
main.c: Her şeyi bir araya getir. Bir type indicator'ı (iinteger,sstring için) ve ardından değeri oku. Appropriate Wrapper'ı Create et, içeriğini yazdır ve memory'yi Free et.
Programın iki input alacak:
- Bir type indicator: integer için
iveya string içins - Wrap edilecek değer
Input'lar i ve 42 olduğunda örnek output:
42Input'lar s ve Hello olduğunda örnek output:
HelloInput'lar i ve -100 olduğunda örnek output:
-100Input'lar s ve Generic Programming olduğunda örnek output:
Generic ProgrammingHeader file'ında include guards kullanmayı unutma. String kopyalama için strlen ve strcpy kullanarak string ve null terminator için yeterli alan allocate et.
Kendin dene
#include <stdio.h>
#include <string.h>
#include "wrapper.h"
int main() {
char type;
scanf("%c", &type);
getchar(); // yeni satırı tüket
Wrapper w;
if (type == 'i') {
int value;
scanf("%d", &value);
// TODO: wrap_int kullanarak bir tamsayı sarmalayıcı oluştur
} else if (type == 's') {
char str[256];
fgets(str, sizeof(str), stdin);
// Varsa sondaki yeni satırı kaldır
str[strcspn(str, "\n")] = '\0';
// TODO: wrap_string kullanarak bir dize sarmalayıcı oluştur
}
// TODO: print_wrapper kullanarak sarmalayıcı içeriğini yazdır
// TODO: free_wrapper kullanarak sarmalayıcı belleğini serbest bırak
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 Kutu7Fonksiyon İşaretçileri
Fonksiyon İşaretçilerini TanımlamaFonksiyon İşaretçilerini ÇağırmaFonksiyon İşaretçileri için TypedefFonksiyonları Argüman Olarak GeçirmeÖzet: Hesap Makinesi Yönlendirme10Jenerik Kapsayıcılar
Void İşaretçiler ÖzetiJenerik SarmalayıcıJenerik Yer DeğiştirmeJenerik KarşılaştırmaÖzet: Jenerik Dizi2Nesneler 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şisiKendi başına pratik yap: Online C derleyicisi