Menu
Coddy logo textTech

Enum Sınıfları ve Güçlü Tiplendirme

Coddy'nin C++ Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 80 / 104.

C++11, geleneksel C tarzı enum'ların eksikliklerini gidermek için enum sınıflarını (kapsamlı numaralandırmalar olarak da adlandırılır) kullanıma sundu. Bunlar daha güçlü tür güvenliği sağlar ve numaralandırma değerlerinin yanlışlıkla hatalı kullanılmasını önler.

Geleneksel enum'ların sorunları vardır: değerleri çevreleyen kapsama sızar ve örtük olarak tamsayılara dönüşür; bu da fark edilmesi zor hatalara yol açar:

// Geleneksel enum - sorunlu
enum Color { Red, Green, Blue };
enum TrafficLight { Red, Yellow, Green };  // Hata! Red ve Green zaten tanımlanmış

int x = Red;  // Örtük olarak int'e dönüştürür (0)
if (Red == 0) { }  // Derlenir - enum'u int ile karşılaştırma

Enum sınıfları, değerleri kapsam içine alarak ve örtük dönüşümleri engelleyerek bu sorunları çözer:

enum class Color { Red, Green, Blue };
enum class TrafficLight { Red, Yellow, Green };  // OK - çakışma yok

Color c = Color::Red;      // Kapsam operatörü kullanılmalı
// int x = c;              // Hata! Örtük dönüşüm yok
int x = static_cast<int>(c);  // Açık dönüşüm gerekli

// if (c == 0) { }         // Hata! int ile karşılaştırılamaz
if (c == Color::Red) { }   // OK - aynı türler karşılaştırılıyor

Bellek denetimi için temel türü de belirtebilirsiniz:

enum class Status : uint8_t {
    Inactive = 0,
    Active = 1,
    Pending = 2
};

Enum sınıfları OOP tasarımlarıyla iyi bir şekilde bütünleşir; kodu daha okunabilir hâle getirir ve tür hatalarını çalışma zamanı yerine derleme zamanında yakalar.

challenge icon

Görev

Kolay

Farklı öncelik düzeylerini ve görev durumlarını temsil etmek için enum sınıflarını kullanan bir görev öncelik sistemi oluşturalım. Bu, enum sınıflarının tür güvenliği sağladığını ve geleneksel enum'larla ortaya çıkan hata türlerini nasıl önlediğini gösterir.

Kodunuzu üç dosyaya ayıracaksınız:

  • TaskTypes.h: Görev sistemi için enum sınıflarınızı tanımlayın.

    Şu değerlere sahip bir Priority enum sınıfı oluşturun: Low, Medium, High ve Critical. Temel tür olarak int belirtin ve sırasıyla 1, 2, 3 ve 4 değerlerini kullanın.

    Şu değerlere sahip bir Status enum sınıfı oluşturun: Pending, InProgress ve Completed.

    İki yardımcı işlev sağlayın:

    • priorityToString(Priority p): önceliği bir dize olarak döndürür ("Low", "Medium", "High" veya "Critical")
    • statusToString(Status s): durumu bir dize olarak döndürür ("Pending", "InProgress" veya "Completed")
  • Task.h: Enum sınıflarınızı kullanan bir Task sınıfı tanımlayın.

    Task sınıfınız bir ad (string), bir Priority ve bir Status saklamalıdır. Yapıcı, bir ad ve öncelik almalı; durum varsayılan olarak Status::Pending olmalıdır.

    Şu yöntemleri uygulayın:

    • setStatus(Status s): görevin durumunu günceller
    • getPriorityValue(): static_cast kullanarak önceliğin temel tamsayı değerini döndürür
    • display(): görevi şu biçimde yazdırır: [name] - Priority: [priority] (Value: [value]) - Status: [status]
  • main.cpp: Üç girdi okuyun:
    1. Görev adı (string)
    2. Tamsayı olarak öncelik düzeyi (1=Low, 2=Medium, 3=High, 4=Critical)
    3. Tamsayı olarak durum (0=Pending, 1=InProgress, 2=Completed)

    Verilen ad ve öncelikle bir Task oluşturun (tamsayıyı Priority kullanarak uygun static_cast enum değerine dönüştürün). Ardından durumunu üçüncü girdiye göre ayarlayın. Son olarak görev ayrıntılarını göstermek için display() yöntemini çağırın.

Örneğin, girdiler Fix bug, 3 ve 1 olduğunda:

Fix bug - Priority: High (Value: 3) - Status: InProgress

Girdiler Write docs, 1 ve 2 olduğunda:

Write docs - Priority: Low (Value: 1) - Status: Completed

Girdiler Deploy app, 4 ve 0 olduğunda:

Deploy app - Priority: Critical (Value: 4) - Status: Pending

Enum sınıflarının öncelik ve durum değerlerini nasıl tamamen ayrı tuttuğuna dikkat edin. Bir Priority ile bir Status değerini yanlışlıkla karşılaştıramaz veya birini diğerine atayamazsınız. Tamsayılar ile enum değerleri arasında dönüşüm yapmak için gereken açık static_cast, kodun amacını netleştirir ve ince hataları önler.

Kendin dene

#include <iostream>
#include <string>
#include "Task.h"

using namespace std;

int main() {
    // Girdileri oku
    string taskName;
    int priorityInt;
    int statusInt;
    
    getline(cin, taskName);
    cin >> priorityInt;
    cin >> statusInt;
    
    // TODO: Verilen ad ve öncelik ile bir Task oluştur
    // priorityInt'i Priority enum'una dönüştürmek için static_cast kullan
    
    // TODO: statusInt'e göre görevin durumunu ayarla
    // statusInt'i Status enum'una dönüştürmek için static_cast kullan
    
    // TODO: Görev detaylarını göstermek için display() çağı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