0Pricing
C++ Academy · درس

الاتحادات ومخاطرها

شارك الذاكرة بين الأنواع

الاتحادات ومخاطرها درس مجاني في C++ Academy على CoddyKit. هذا هو الدرس 2 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في C++ Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة C++ Academy 4 دروس في المجموع.

ما هو الاتحاد؟

يتيح union لعدة أعضاء مشاركة الذاكرة نفسها. ويكون عضو واحد فقط صالحًا في كل مرة، ولا يكون حجم الاتحاد أكبر من حجم أكبر أعضائه.

#include <iostream>
union Number {
    int i;
    float f;
};
int main() {
    Number n;
    n.i = 42;
    std::cout << n.i << "\n";
}

حجم الاتحاد

بما أن الأعضاء متراكبة، يساوي sizeof الاتحاد حجم أكبر أعضائه (بالإضافة إلى أي حشو للمحاذاة)، وليس مجموع أحجامها.

#include <iostream>
union Mix { char c; int i; double d; };
int main() {
    std::cout << sizeof(Mix) << "\n"; // size of double (often 8)
}

الكتابة في عضو وقراءة عضو آخر

الكتابة في أحد الأعضاء وقراءة عضو مختلف هي المخاطرة الأساسية. إذ يعاد تفسير البتات، وغالبًا ما يؤدي ذلك إلى سلوك غير معرّف أو نتائج مفاجئة.

#include <iostream>
union Bits { int i; float f; };
int main() {
    Bits b;
    b.f = 1.0f;
    std::cout << b.i << "\n"; // reads float bits as int
}

عضو نشط واحد فقط

العضو الذي كتبتم فيه أخيرًا هو العضو الوحيد الذي يمكنكم قراءته بأمان. عليكم تتبّع العضو «النشط» بأنفسكم؛ فالـ union لا يتذكّر ذلك.

#include <iostream>
union Value { int i; double d; };
int main() {
    Value v;
    v.d = 3.14;        // d is active
    std::cout << v.d << "\n";
}

نمط الاتحاد المعلَّم

لاستخدام unions بأمان، اربطوها مع وسم (enum) يسجّل العضو النشط. وهذا هو السلف اليدوي لـ std::variant.

#include <iostream>
struct Tagged {
    enum { Int, Double } tag;
    union { int i; double d; };
};
int main() {
    Tagged t; t.tag = Tagged::Int; t.i = 7;
    if (t.tag == Tagged::Int) std::cout << t.i << "\n";
}

قراءة العضو الصحيح

تفرّعوا دائمًا بناءً على الوسم قبل القراءة. تؤدي قراءة العضو الخطأ إلى إنتاج قيم عشوائية.

#include <iostream>
struct Tagged {
    enum { Int, Double } tag;
    union { int i; double d; };
};
void print(const Tagged& t) {
    if (t.tag == Tagged::Int) std::cout << "int " << t.i << "\n";
    else std::cout << "double " << t.d << "\n";
}
int main() { Tagged t{Tagged::Double}; t.d = 2.5; print(t); }

الأعضاء غير البسيطة

إن وضع عضو له constructor أو destructor (مثل std::string) داخل union يتطلب إنشاءه وتدميره يدويًا. وهذا عرضة للأخطاء، وهو سبب آخر لتفضيل std::variant.

الاتحادات المجهولة

لا يحمل الاتحاد المجهول اسمًا؛ ويمكن الوصول إلى أعضائه مباشرةً. وهو مفيد داخل struct، لكن قاعدة العضو النشط نفسها تظل مطبّقة.

#include <iostream>
struct Packet {
    int kind;
    union { int code; char letter; };
};
int main() {
    Packet p; p.kind = 1; p.code = 99;
    std::cout << p.code << "\n";
}

لماذا تُعد الاتحادات محفوفة بالمخاطر

ملخّص المخاطر:

  • لا توجد معلومات عن العضو النشط.
  • قراءة عضو غير نشط هي سلوك غير معرّف.
  • تحتاج الأنواع غير البسيطة إلى إدارة يدوية لدورة حياتها.

متى تظل الاتحادات مفيدة

تظل الاتحادات مفيدة في الأعمال منخفضة المستوى: لإعادة تفسير البايتات، أو لتوفير الذاكرة في الشيفرة المضمّنة ذات القيود الصارمة، أو لمطابقة تخطيط ثنائي ثابت. أما في بيانات «نوع واحد من عدة أنواع» المعتادة، ففضّلوا البديل الأكثر أمانًا.

نحو std::variant

إن std::variant هو union آمن من ناحية الأنواع، إذ يتتبّع النوع النشط نيابةً عنكم ويرمي استثناءً عند الوصول إلى النوع الخطأ. يستكشف باقي هذه الدورة استخدامه.

تحقق سريع

تحقّقوا من فهمكم للاتحادات.

مراجعة

تعلّمتم عن الاتحادات:

  • يشترك جميع الأعضاء في كتلة واحدة من الذاكرة.
  • العضو المكتوب فيه أخيرًا هو العضو الوحيد الصالح للقراءة.
  • استخدموا وسمًا (enum) لتتبّع العضو النشط.
  • فضّلوا std::variant لتحقيق الأمان في C++ الحديثة.

الأسئلة الشائعة

هل درس «الاتحادات ومخاطرها» مجاني؟

نعم — نص درس «الاتحادات ومخاطرها» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة C++ Academy، انتقل إلى CoddyKit PRO. تتضمن دورة C++ Academy 4 دروس في المجموع.

ماذا ستتعلم في «الاتحادات ومخاطرها»؟

شارك الذاكرة بين الأنواع تتمرن على C++ Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ C++ Academy؟

لا تُشترط خبرة سابقة. C++ Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 2 من أصل 4.

كم من الوقت يستغرق درس «الاتحادات ومخاطرها»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس C++ Academy هذا؟

نعم. كل درس في C++ Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. enum class ذات نطاق
  2. الاتحادات ومخاطرها
  3. std::variant
  4. std::visit
← العودة إلى C++ Academy