Menu
Coddy logo textTech

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ı: 50

Bu, 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.

challenge icon

Görev

Kolay

Eylem 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 bir Vehicle yapısı oluştur: speed (mevcut hız için bir tamsayı) ve max_speed (aracın azami hızı için bir tamsayı). Ardından, ilk üyesi olarak Motorcycle içeren ve bir Vehicle alanı ekleyen (1'in evet, 0'ın hayır anlamına geldiği bir tamsayı) bir has_sidecar yapısı tanımla. İki işlev bildir: bir boost ve hızı artırılacak miktarı alan Vehicle* ile bir print_motorcycle alan Motorcycle*.
  • vehicle.c: Her iki işlevi de uygula. boost işlevin aracın hızını verilen miktar kadar artırmalı, ancak bunu max_speed değeriyle sınırlamalı; yeni hız azami değeri aşacaksa bunun yerine max_speed olarak ayarla. print_motorcycle işlevin, içindeki araç verileri de dâhil olmak üzere motosikletin tüm bilgilerini görüntülemeli.
  • main.c: Bir Motorcycle oluştur ve tüm alanlarını başlat. Ardından boost işlevini çağırarak upcasting'i göster: bu genel işleve geçirmek için Motorcycle* 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: Yes

Burada 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;
}
quiz iconKendini test et

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

Kendi başına pratik yap: Online C derleyicisi