Upcasting
Coddy'nin C Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 31 / 61.
Yukarı dönüştürme, belirli (türetilmiş) bir 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 struct işaretçisini temel türü bekleyen bir işleve geçirmek anlamına gelir.
Bir Vehicle temel yapısını ve bunu içeren bir Car yapısını göz önünde bulundurun:
typedef struct {
int speed;
} Vehicle;
typedef struct {
Vehicle vehicle; // İlk üye olarak temel yapı
int doors;
} Car;Şimdi herhangi bir araçla çalışan genel amaçlı bir işlev hayal et:
void accelerate(Vehicle* v, int amount) {
v->speed += amount;
}İlk üye kuralı sayesinde, Car* değerini Vehicle* türüne dönüştürerek bu işleve aktarabiliriz:
Car my_car = {{0}, 4}; // speed=0, doors=4
accelerate((Vehicle*)&my_car, 50);
printf("Speed: %d\n", my_car.vehicle.speed); // Çıktı: 50Bu, upcasting işlemidir: belirli bir türden genel bir türe doğru “yukarı” çıkıyoruz. accelerate işlevi bir Car ile çalıştığını bilmez; yalnızca bir Vehicle görür. Bu sayede temel tür üzerinde çalışan ve onu içeren herhangi bir türetilmiş türü kabul eden yeniden kullanılabilir kod yazabilirsin.
Görev
KolayUpcasting işlemini uygulamalı olarak gösteren basit bir ulaşım sistemi oluşturalım. Bir temel Vehicle türü ve daha özel bir Motorcycle türü oluşturacak, ardından genel bir işlevin işaretçi dönüşümü aracılığıyla her ikisiyle de nasıl çalışabileceğini göstereceksin.
Upcasting'in gücü, temel tür için işlevler yazabilmen ve bu işlevlerin onu içine alan tüm türetilmiş türlerle sorunsuzca çalışmasıdır. Motosikletin bir araçtır; bu nedenle Vehicle* bekleyen herhangi bir işlev onu işleyebilmelidir.
Kodunu üç dosyaya düzenleyeceksin:
vehicle.h: Include guard'larıyla yapı hiyerarşini tanımla. İki alanı olan birVehicleyapısı oluştur:speed(mevcut hız için bir tam sayı) vemax_speed(aracın azami hızı için bir tam sayı). Ardından, ilk üyesi olarakVehicleyapısını içine alan vehas_sidecaralanını ekleyen birMotorcycleyapısı tanımla (bu alan bir tam sayıdır; 1 evet, 0 hayır anlamına gelir). İki işlev bildir:boost, birVehicle*ve hızı artıracak bir miktar alır;print_motorcycleise birMotorcycle*alır.vehicle.c: Her iki işlevi de uygula.boostişlevin aracın hızını verilen miktar kadar artırmalı, ancakmax_speedile sınırlamalıdır; yeni hız azami hızı aşacaksa bunun yerine hızımax_speedolarak ayarla.print_motorcycleişlevin, içine aldığı araç verileri de dahil olmak üzere motosikletin tüm bilgilerini göstermelidir.main.c: BirMotorcycleoluştur ve tüm alanlarını başlat. Ardındanboostişlevini çağırarak upcasting işlemini göster: bu genel işleve aktarabilmek içinMotorcycle*türünüVehicle*türüne dönüştür. Hızı artırdıktan 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 şöyle görünmelidir:
Speed: 75
Max Speed: 120
Sidecar: YesBurada 75 hız artırma işleminden sonraki hızdır (başlangıçta 50 + artırma miktarı 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ı azami hızın ü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. Yalnızca Vehicle ile çalışır. Ancak upcasting sayesinde motosikletin, içine aldığı 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, ilk üyesi olarak Vehicle içerir
// TODO: boost işlevini çağırarak üst türe dönüştürmeyi göster
// boost işlevine geçirmek için Motorcycle* türündeki değeri Vehicle* türüne dönüştür
// 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