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ırmaEnum 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ıyorBellek 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.
Görev
KolayFarklı ö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
Priorityenum sınıfı oluşturun:Low,Medium,HighveCritical. Temel tür olarakintbelirtin ve sırasıyla 1, 2, 3 ve 4 değerlerini kullanın.Şu değerlere sahip bir
Statusenum sınıfı oluşturun:Pending,InProgressveCompleted.İ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 birTasksınıfı tanımlayın.Tasksınıfınız bir ad (string), birPriorityve birStatussaklamalıdır. Yapıcı, bir ad ve öncelik almalı; durum varsayılan olarakStatus::Pendingolmalıdır.Şu yöntemleri uygulayın:
setStatus(Status s): görevin durumunu güncellergetPriorityValue():static_castkullanarak önceliğin temel tamsayı değerini döndürürdisplay(): görevi şu biçimde yazdırır:[name] - Priority: [priority] (Value: [value]) - Status: [status]
main.cpp: Üç girdi okuyun:- Görev adı (string)
- Tamsayı olarak öncelik düzeyi (1=Low, 2=Medium, 3=High, 4=Critical)
- Tamsayı olarak durum (0=Pending, 1=InProgress, 2=Completed)
Verilen ad ve öncelikle bir
Taskoluşturun (tamsayıyıPrioritykullanarak uygunstatic_castenum 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çindisplay()yöntemini çağırın.
Örneğin, girdiler Fix bug, 3 ve 1 olduğunda:
Fix bug - Priority: High (Value: 3) - Status: InProgressGirdiler Write docs, 1 ve 2 olduğunda:
Write docs - Priority: Low (Value: 1) - Status: CompletedGirdiler Deploy app, 4 ve 0 olduğunda:
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. 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;
}
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 KonteynerKendi başına pratik yap: Online C++ derleyicisi