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 classes (kapsamlı numaralandırmalar olarak da adlandırılır) yapısını tanıttı. Bunlar daha güçlü tip güvenliği sağlar ve numaralandırma değerlerinin yanlışlıkla hatalı kullanımını önlerler.

Geleneksel enum'ların sorunları vardır: değerleri çevreleyen kapsama sızar ve örtük olarak tam sayılara dönüşerek sinsi 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 (0) dönüşür
if (Red == 0) { }  // Derlenir - enum ile int karşılaştırılıyor

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 };  // Tamam - çakışma yok

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

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

Bellek kontrolü 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 entegre olur; kodu daha okunabilir hale getirir ve tür hatalarını çalışma zamanı yerine derleme zamanında yakalar.

challenge icon

Görev

Kolay

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

Kodunuzu üç dosya halinde düzenleyeceksiniz:

  • 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 değerleri sırasıyla 1, 2, 3 ve 4 olsun.

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

    İki yardımcı fonksiyon 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 isim (string), bir Priority ve bir Status saklamalıdır. Kurucu (constructor) bir isim ve öncelik almalı, durum varsayılan olarak Status::Pending olmalıdır.

    Şu metotları 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 formatta yazdırır: [name] - Priority: [priority] (Value: [value]) - Status: [status]
  • main.cpp: Üç girdi okuyun:
    1. Görev adı (string)
    2. Tamsayı olarak öncelik seviyesi (1=Low, 2=Medium, 3=High, 4=Critical)
    3. Tamsayı olarak durum (0=Pending, 1=InProgress, 2=Completed)

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

Örneğin, Fix bug, 3 ve 1 girdileriyle:

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

Write docs, 1 ve 2 girdileriyle:

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

Deploy app, 4 ve 0 girdileriyle:

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; yanlışlıkla bir Priority değerini bir Status değeriyle karşılaştıramaz veya birini diğerine atayamazsınız. Tamsayılar ve enum değerleri arasında dönüşüm yapmak için gereken açık static_cast kullanımı, kodun amacını netleştirir ve sinsi 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 isim ve öncelik ile bir Task oluşturun
    // priorityInt değerini Priority enum türüne dönüştürmek için static_cast kullanın
    
    // TODO: statusInt değerine göre görevin durumunu ayarlayın
    // statusInt değerini Status enum türüne dönüştürmek için static_cast kullanın
    
    // TODO: Görev ayrıntılarını göstermek için display() fonksiyonunu çağırın
    
    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