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) özelliğini getirdi. Bunlar daha güçlü tür güvenliği sağlar ve numaralandırma değerlerinin yanlışlıkla hatalı kullanımını önler.
Geleneksel enum'ların sorunları vardır: değerleri çevreleyen kapsama sızar ve dolaylı olarak tam sayılara dönüşerek 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; // Dolaylı olarak int'e (0) dönüşür
if (Red == 0) { } // Derlenir - enum ile int karşılaştırılıyorEnum 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ıyorBellek 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.
Görev
KolayFarklı öncelik seviyelerini 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 nasıl tip 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
Priorityenum sınıfı oluşturun:Low,Medium,HighveCritical. Temel tür olarakintbelirtin ve değerleri sırasıyla 1, 2, 3 ve 4 olsun.Şu değerlere sahip bir
Statusenum sınıfı oluşturun:Pending,InProgressveCompleted.İ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 birTasksınıfı tanımlayın.Tasksınıfınız bir isim (string), birPriorityve birStatussaklamalıdır. Kurucu (constructor) bir isim ve öncelik almalı, durum varsayılan olarakStatus::Pendingolmalıdır.Şu metotları uygulayın:
setStatus(Status s)— görevin durumunu güncellergetPriorityValue()—static_castkullanarak önceliğin temel tam sayı değerini döndürürdisplay()— görevi şu formatta yazdırır:[name] - Priority: [priority] (Value: [value]) - Status: [status]
main.cpp: Üç girdi okuyun:- Görev adı (string)
- Tam sayı olarak öncelik seviyesi (1=Low, 2=Medium, 3=High, 4=Critical)
- Tam sayı olarak durum (0=Pending, 1=InProgress, 2=Completed)
Verilen isim ve öncelik ile bir
Taskoluşturun (tam sayıyıstatic_castkullanarak uygunPriorityenum 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çindisplay()metodunu çağırın.
Örneğin, Fix bug, 3 ve 1 girdileriyle:
Fix bug - Priority: High (Value: 3) - Status: InProgressWrite docs, 1 ve 2 girdileriyle:
Write docs - Priority: Low (Value: 1) - Status: CompletedDeploy app, 4 ve 0 girdileriyle:
Deploy app - Priority: Critical (Value: 4) - Status: PendingEnum 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. Tam sayı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.
Kopya kağıdı
C++11, geleneksel C tarzı enum'lardan daha güçlü tip güvenliği sağlamak için enum sınıflarını (kapsamlı numaralandırmalar - scoped enumerations) tanıttı.
Geleneksel enum'lar, kapsam sızıntısı (scope leakage) ve örtük dönüşümlerle (implicit conversions) ilgili sorunlara sahiptir:
// Geleneksel enum - problemli
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üşür
if (Red == 0) { } // Derlenir - enum ile int karşılaştırılıyorEnum sınıfları, kapsam çözünürlüğü (scope resolution) gerektirerek 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ı
// int x = c; // Hata! Örtük dönüşüm yok
int x = static_cast<int>(c); // Açık dönüşüm (explicit conversion) gerekli
// if (c == 0) { } // Hata! int ile karşılaştırılamaz
if (c == Color::Red) { } // Tamam - aynı tipler karşılaştırılıyorBellek kontrolü için temel veri tipini (underlying type) belirtebilirsiniz:
enum class Status : uint8_t {
Inactive = 0,
Active = 1,
Pending = 2
};Enum sınıfları ve tam sayılar arasında dönüşüm yapmak için açık döküm (explicit casting) kullanın:
// Tam sayıdan enum sınıfına
Priority p = static_cast<Priority>(3);
// Enum sınıfından tam sayıya
int value = static_cast<int>(p);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 (status) 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;
}
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
1OOP Temelleri
Harici DosyalarC++ Build ve DerlemeBaşlık Dosyaları ve Kaynak DosyalarıAd Alanları ve KapsamC++'ta OOP'ye GirişSınıflar ve Nesneler'this' İşaretçisiMetotlar (Üye Fonksiyonlar)Öznitelikler (Veri Üyeleri)Ctor ve Dtor TemelleriÖzet - Basit Hesap Makinesi4Sınıf Özellikleri
Örnek ve Statik ÜyelerGetter ve Setter MetotlarıConst Üye FonksiyonlarMutable Anahtar KelimesiStatik Metotlar ve DeğişkenlerFriend Fonksiyonlar ve SınıflarÖzet - Banka Hesabı Yöneticisi7Kalıtım
Temel KalıtımKalıtım Erişim SeviyeleriCtor ve Dtor Çağrılma SırasıMetot Geçersiz KılmaSanal Fonksiyonlar ve VTableÇoklu KalıtımSanal KalıtımÖzet - Çalışan Hiyerarşisi10STL Genel Bakış
STL Genel Bakış ve FelsefesiSTL KonteynerleriİteratörlerSTL AlgoritmalarıFunctor'lar ve Lambda İfadeleriÖzet - Kelime Frekansı13Tasarım Kalıpları 1. Bölüm
Tasarım Kalıplarına GirişSingleton KalıbıFactory ve Abstract FactoryBuilder KalıbıObserver KalıbıStrategy Kalıbı2Bellek Yönetimi
Stack ve Heap Bellekİşaretçiler ve ReferanslarDinamik Bellek (new/delete)C++'ta Akıllı İşaretçilerC++'ta RAIIÖzet - Dinamik Dizi Yöneticisi5Kapsülleme
C++'da Erişim BelirleyicilerDerinlemesine Erişim BelirleyicilerBilgi GizlemeStruct vs Classİç İçe ve Dahili SınıflarÖzet - Öğrenci Kayıt Sistemi8Çok Biçimlilik
Derleme ve Çalışma Zamanı Çok BiçimliliğiFonksiyon Aşırı YüklemeSanal Fonksiyonlara Yeniden BakışSaf Sanal FonksiyonlarSoyut SınıflarC++'ta Arayüz TasarımıDynamic Casting ve RTTIÖzet - Şekil Hesaplayıcı11İleri Düzey OOP Kavramları
Kompozisyon ve Kalıtım KarşılaştırmasıCRTP ile Mixin YapılarıPimpl İdiyomuTür Silme (Type Erasure)Enum Sınıfları ve Güçlü TiplendirmeOOP'de İstisna YönetimiÖzel İstisna Hiyerarşileri3Yapıcılar ve Yıkıcılar
Varsayılan YapıcıParametreli YapıcıKopya YapıcıTaşıma YapıcısıYapıcı İlklendirme ListeleriTemsilci YapıcılarYıkıcılara Derinlemesine BakışÜç / Beş / Sıfır KuralıÖzet - String Sınıfı6Operatör Aşırı Yükleme
Operatör Aşırı Yüklemeye GirişAritmetik Operatör Aşırı YüklemeKarşılaştırma Operatörü Aşırı YüklemeStream OperatörleriAtama Operatörü Aşırı Yükleme[] ve () Operatör Aşırı YüklemeTip Dönüşüm OperatörleriÖzet - Matris Sınıfı9Şablonlar
Fonksiyon ŞablonlarıSınıf ŞablonlarıŞablon ÖzelleştirmeVariadic ŞablonlarSFINAE ve Type Traits TemelleriÖzet - Generic Konteyner