Upcasting
Coddy'nin C Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 31 / 61.
Üst türe dönüştürme, belirli bir (türetilmiş) türü daha genel (temel) türüymüş gibi ele alma işlemidir. C'nin bileşim modelinde bu, temel türü içeren bir yapıya işaretçiyi temel türü bekleyen bir işleve geçirme anlamına gelir.
Bir Vehicle temel yapısını ve onu içeren bir Car yapısını düşünün:
typedef struct {
int speed;
} Vehicle;
typedef struct {
Vehicle vehicle; // Temel ilk üye olarak
int doors;
} Car;Şimdi herhangi bir araçla çalışan genel bir işlev hayal et:
void accelerate(Vehicle* v, int amount) {
v->speed += amount;
}İlk üye kuralı sayesinde, bir Car* değerini Vehicle* türüne dönüştürerek bu işleve geçirebiliriz:
Car my_car = {{0}, 4}; // speed=0, doors=4
accelerate((Vehicle*)&my_car, 50);
printf("Speed: %d\n", my_car.vehicle.speed); // Çıktı: 50Bu, yukarı tür dönüşümüdür: belirli bir türden genel bir türe doğru “yukarı” hareket ediyoruz. accelerate işlevi bir Car ile çalıştığını bilmez; yalnızca bir Vehicle görür. Bu, temel tür üzerinde çalışırken onu içeren herhangi bir türetilmiş türü kabul eden yeniden kullanılabilir kod yazmanıza olanak tanır.
Görev
KolayEylem hâlindeki upcasting'i gösterecek basit bir ulaşım sistemi oluşturalım. Bir temel Vehicle türü ve daha özel bir Motorcycle türü oluşturacak, ardından bir genel işlevin işaretçi dönüştürme yoluyla her ikisiyle nasıl çalışabildiğini göstereceksin.
Upcasting'in gücü, temel tür için işlevler yazabilmen ve bu işlevlerin, temel türü içeren tüm türetilmiş türlerle sorunsuz şekilde çalışabilmesidir. Motosikletin bir "araçtır"; bu nedenle Vehicle* bekleyen herhangi bir işlev onu işleyebilmelidir.
Kodunu üç dosyaya ayıracaksın:
vehicle.h: Include guard'larıyla yapı hiyerarşini tanımla. İki alana sahip birVehicleyapısı oluştur:speed(mevcut hız için bir tamsayı) vemax_speed(aracın azami hızı için bir tamsayı). Ardından, ilk üyesi olarakMotorcycleiçeren ve birVehiclealanı ekleyen (1'in evet, 0'ın hayır anlamına geldiği bir tamsayı) birhas_sidecaryapısı tanımla. İki işlev bildir: birboostve hızı artırılacak miktarı alanVehicle*ile birprint_motorcyclealanMotorcycle*.vehicle.c: Her iki işlevi de uygula.boostişlevin aracın hızını verilen miktar kadar artırmalı, ancak bunumax_speeddeğeriyle sınırlamalı; yeni hız azami değeri aşacaksa bunun yerinemax_speedolarak ayarla.print_motorcycleişlevin, içindeki araç verileri de dâhil olmak üzere motosikletin tüm bilgilerini görüntülemeli.main.c: BirMotorcycleoluştur ve tüm alanlarını başlat. Ardındanboostişlevini çağırarak upcasting'i göster: bu genel işleve geçirmek içinMotorcycle*türünüVehicle*türüne dönüştür. Hız artırma işleminden sonra sonucu görmek için motosikletin bilgilerini yazdır.
Dört girdi alacaksın: motosikletin başlangıç hızı, azami hızı, yan sepeti olup olmadığı (1 veya 0) ve hız artırma miktarı.
Çıktın şu şekilde görünmeli:
Speed: 75
Max Speed: 120
Sidecar: YesBurada 75, hız artırma işleminden sonraki hızdır (başlangıçta 50 + artırma 25); 120, azami hızdır ve Yes veya No, motosikletin yan sepeti olup olmadığını belirtir. Hız artırma işlemi hızı max_speed değerinin üzerine çıkaracaksa hız max_speed ile sınırlandırılmalıdır.
Buradaki temel öğrenme noktası, boost işlevinin motosikletler hakkında hiçbir şey bilmemesidir. Bu işlev yalnızca Vehicle ile çalışır. Ancak upcasting sayesinde motosikletin, içindeki araç verilerini değiştirmek için bu genel işlevi kullanabilir.
Kendin dene
#include <stdio.h>
#include "vehicle.h"
int main() {
int initial_speed, max_speed, has_sidecar, boost_amount;
// Girdileri oku
scanf("%d", &initial_speed);
scanf("%d", &max_speed);
scanf("%d", &has_sidecar);
scanf("%d", &boost_amount);
// TODO: Bir Motorcycle oluştur ve tüm alanlarını başlat
// Unutma: Motorcycle, Vehicle'ı ilk üyesi olarak içerir
// TODO: boost çağırarak upcasting'i göster
// boost fonksiyonuna geçirmek için Motorcycle*'ınızı Vehicle*'a cast edin
// TODO: Motosikletin bilgilerini yazdır
return 0;
}
Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Nesne Yönelimli Programlama 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şisiKendi başına pratik yap: Online C derleyicisi