enum class ذات نطاق
تعدادات آمنة من ناحية النوع
enum class ذات نطاق درس مجاني في C++ Academy على CoddyKit. هذا هو الدرس 1 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في C++ Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة C++ Academy 4 دروس في المجموع.
التعدادات العادية تسرّب الأسماء
يلقي enum التقليدي بأسلوب C أسماءه في النطاق المحيط، ويحوّلها ضمنيًا إلى int. وهذا يجعل تعارض الأسماء والمقارنات غير المقصودة أمرين سهلَي الوقوع.
- يحل enum class المشكلتين.
- تكون القيم محصورة النطاق ومحددة النوع بقوة.
#include <iostream>
enum Color { Red, Green, Blue };
int main() {
Color c = Green;
int x = c; // implicit conversion to int
std::cout << x << "\n";
}تعريف تعداد محصور النطاق
أضف الكلمة المفتاحية class (أو struct) لإنشاء تعداد محصور النطاق. عندها يجب تأهيل كل قيمة باسم التعداد.
#include <iostream>
enum class Color { Red, Green, Blue };
int main() {
Color c = Color::Green;
if (c == Color::Green) std::cout << "green\n";
}لا يوجد تحويل ضمني
لا يتحول التعداد المحصور النطاق ضمنيًا إلى int. ويمنع ذلك الأخطاء التي يُستخدم فيها التعداد في العمليات الحسابية عن طريق الخطأ.
- للحصول على الرقم، يجب إجراء تحويل صريح.
#include <iostream>
enum class Color { Red, Green, Blue };
int main() {
Color c = Color::Blue;
int n = static_cast<int>(c); // explicit
std::cout << n << "\n"; // prints 2
}النوع الأساسي
يكون النوع الأساسي int افتراضيًا، لكن يمكنك اختيار نوع عدد صحيح أصغر أو محدد لتوفير المساحة أو لمطابقة بروتوكول.
#include <iostream>
#include <cstdint>
enum class Status : std::uint8_t { Ok = 0, Warn = 1, Error = 2 };
int main() {
Status s = Status::Warn;
std::cout << static_cast<int>(s) << "\n";
}قيم مخصصة
يمكنك إسناد قيم صريحة إلى عناصر التعداد. وتتابع القيم اللاحقة العد بدءًا من القيمة الصريحة.
#include <iostream>
enum class Http { Ok = 200, NotFound = 404, ServerError = 500 };
int main() {
Http h = Http::NotFound;
std::cout << static_cast<int>(h) << "\n";
}استخدام التعداد في switch
تتألق التعدادات داخل عبارات switch. ويجعل إدراج كل حالة القصد واضحًا، كما يتيح للمصرّف التحذير من الحالات المفقودة.
#include <iostream>
enum class Dir { North, East, South, West };
const char* name(Dir d) {
switch (d) {
case Dir::North: return "N";
case Dir::East: return "E";
case Dir::South: return "S";
case Dir::West: return "W";
}
return "?";
}
int main() { std::cout << name(Dir::East) << "\n"; }التعدادات كوسائط للدوال
يوضح تمرير تعداد محصور النطاق القصد بدرجة أكبر بكثير من تمرير int أو bool مجرد. ويفرض المصرّف استخدام قيم تعداد صالحة فقط.
#include <iostream>
enum class Align { Left, Center, Right };
void render(const char* text, Align a) {
std::cout << text << " aligned " << static_cast<int>(a) << "\n";
}
int main() { render("Hi", Align::Center); }مقارنة قيم التعداد
تدعم التعدادات المحصورة النطاق العاملين == و!= مباشرةً. وتعمل أيضًا العوامل العلائقية (< و>) لأن القيم مرتبة.
#include <iostream>
enum class Level { Low, Medium, High };
int main() {
Level l = Level::High;
std::cout << (l > Level::Low ? "above low\n" : "low\n");
}التكرار بصورة مفاهيمية
لا تتكرر التعدادات تلقائيًا، لكن من الأنماط الشائعة إجراء تحويل عبر الأعداد الصحيحة الأساسية. احتفظ بقيمة حارسة مثل Count لمعرفة النطاق.
#include <iostream>
enum class Coin { Penny, Nickel, Dime, Count };
int main() {
for (int i = 0; i < static_cast<int>(Coin::Count); ++i)
std::cout << i << " ";
std::cout << "\n";
}لماذا تهم سلامة الأنواع؟
لا يمكن خلط تعدادين محصورين غير مرتبطين عن طريق الخطأ، حتى لو احتوى كلاهما على قيمة باسم None. ويعاملهما المصرّف كنوعين مختلفين.
#include <iostream>
enum class Fruit { None, Apple };
enum class Tool { None, Hammer };
int main() {
Fruit f = Fruit::None;
// Tool t = f; // would NOT compile
std::cout << (f == Fruit::None) << "\n";
}متى تستخدم التعدادات العادية
لا تزال التعدادات العادية تظهر في واجهات برمجة التطبيقات القديمة وشيفرات أعلام البتات، حيث يكون التحويل الضمني إلى int ملائمًا. أما في الشيفرة الجديدة، ففضّل enum class ما لم يكن لديك سبب محدد.
تحقق سريع
اختبر مدى فهمك للتعدادات المحصورة النطاق.
مراجعة
تعلّمت التعدادات المحصورة النطاق:
- يحصر
enum classنطاق القيم ويمنع التحويل الضمني إلى int. - استخدم
static_cast<int>لقراءة الرقم. - اختر نوعًا أساسيًا باستخدام
: type. - فضّل
enum classلشيفرة آمنة من ناحية الأنواع وموضّحة لذاتها.
الأسئلة الشائعة
هل درس «enum class ذات نطاق» مجاني؟
نعم — نص درس «enum class ذات نطاق» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة C++ Academy، انتقل إلى CoddyKit PRO. تتضمن دورة C++ Academy 4 دروس في المجموع.
ماذا ستتعلم في «enum class ذات نطاق»؟
تعدادات آمنة من ناحية النوع تتمرن على C++ Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ C++ Academy؟
لا تُشترط خبرة سابقة. C++ Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 1 من أصل 4.
كم من الوقت يستغرق درس «enum class ذات نطاق»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس C++ Academy هذا؟
نعم. كل درس في C++ Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- enum class ذات نطاق
- الاتحادات ومخاطرها
- std::variant
- std::visit