0Pricing
C++ Academy · درس

Mixins باستخدام CRTP

كوّن السلوك وقت الترجمة

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

ما هو Mixin؟

إن mixin وحدة صغيرة قابلة لإعادة الاستخدام من السلوك، تُركَّب داخل فئة. باستخدام CRTP، تضيف mixins الوظائف وقت الترجمة مع استمرار استدعائها للفئة المضيفة.

Mixin بسيط

يضيف هذا الـmixin دالة print_twice التي تعتمد على توفير الفئة المضيفة للدالة value().

#include <iostream>

template <typename T>
struct PrintTwice {
    void print_twice() const {
        auto v = static_cast<const T*>(this)->value();
        std::cout << v << " " << v << "\n";
    }
};

struct Box : PrintTwice<Box> {
    int value() const { return 7; }
};

int main() {
    Box{}.print_twice();
    return 0;
}

تركيب عدة Mixins

يمكنك التوارث من عدة CRTP mixins في الوقت نفسه، لتجميع سلوكيات مستقلة داخل فئة واحدة.

#include <iostream>

template <typename T>
struct Loggable {
    void log() const { std::cout << "log: " << static_cast<const T*>(this)->id() << "\n"; }
};

template <typename T>
struct Resettable {
    void reset() { static_cast<T*>(this)->set(0); }
};

struct Device : Loggable<Device>, Resettable<Device> {
    int v = 5;
    int id() const { return v; }
    void set(int x) { v = x; }
};

int main() {
    Device d;
    d.log();
    d.reset();
    d.log();
    return 0;
}

تضيف Mixins الحالة أيضًا

يمكن أن يحتوي الـmixin على أعضاء بيانات خاصة به، وتصبح هذه الأعضاء جزءًا من تخطيط الكائن المركب.

#include <iostream>

template <typename T>
struct Tagged {
    int tag = 0;
    void set_tag(int t) { tag = t; }
    int get_tag() const { return tag; }
};

struct Item : Tagged<Item> {
    const char* name = "item";
};

int main() {
    Item it;
    it.set_tag(42);
    std::cout << it.name << " " << it.get_tag() << "\n";
    return 0;
}

Mixin مقابل التوارث العادي

يختلف CRTP mixin عن التوارث العادي لأن الفئة الأساسية تستطيع الاستدعاء إلى أسفل وصولًا إلى الفئة المشتقة. لا تستطيع الفئات الأساسية العادية استدعاء الدوال الموجودة في النوع المشتق فقط من دون استخدام الدوال الافتراضية.

التصميم القائم على السياسات

تمكّن Mixins من التصميم القائم على السياسات: إذ تُحدَّد السلوكيات وقت الترجمة باختيار الـmixins التي سيتم التوارث منها، على نحو مشابه للطريقة التي يتلقى بها std::vector سياسة مخصّص الذاكرة.

الترتيب والتخطيط

عند تكديس mixins، يؤثر ترتيب الفئات الأساسية في ترتيب الإنشاء وتخطيط الكائن. حافظ على استقلالية mixins حتى لا يؤثر الترتيب في صحة التنفيذ.

  • يتم الإنشاء وفق ترتيب التصريح بالفئات الأساسية
  • تجنّب الـmixins التي تعتمد على بعضها

إضافة Mixin للمساواة

ينشئ هذا الـmixin الدالة operator!= بالاعتماد على دالة المساواة في الفئة المضيفة.

#include <iostream>

template <typename T>
struct EqualityMixin {
    friend bool operator!=(const T& a, const T& b) { return !(a == b); }
};

struct P : EqualityMixin<P> {
    int x;
    P(int v) : x(v) {}
    friend bool operator==(const P& a, const P& b) { return a.x == b.x; }
};

int main() {
    std::cout << (P(1) != P(2)) << "\n";
    return 0;
}

Mixins شرطية

يمكنك تضمين mixin فقط عند تحقق شرط ما، وذلك بدمج التوارث مع std::conditional للاختيار بين mixin حقيقي وآخر فارغ.

تحسين الفئة الأساسية الفارغة

تستفيد الـmixins التي لا تحتوي على أعضاء بيانات من تحسين الفئة الأساسية الفارغة: إذ يخصّص لها المترجم صفر بايتات إضافية، ولذلك لا يترتب على تكديس العديد من mixins عديمة الحالة أي تكلفة من حيث الحجم.

#include <iostream>

template <typename T>
struct A {};
template <typename T>
struct B {};

struct C : A<C>, B<C> {
    int x;
};

int main() {
    std::cout << (sizeof(C) == sizeof(int)) << "\n";
    return 0;
}

متى تستخدم Mixins

تتألق Mixins عندما تحتاج فئات كثيرة إلى السلوكيات المتعامدة نفسها، مثل التسجيل والعد والمقارنة. فهي تُبقي كل سلوك في مكان واحد، وتتيح تركيبه من دون تكلفة وقت تشغيل.

اختبار سريع

اختبر مدى استيعابك لـ CRTP mixins.

مراجعة

تعلّمت إنشاء mixins باستخدام CRTP.

  • تُركّب Mixins السلوكيات المتعامدة وقت الترجمة
  • يمكنها الاستدعاء إلى أسفل وصولًا إلى الفئة المضيفة، كما يمكنها حمل الحالة
  • لا تكلّف Mixins عديمة الحالة شيئًا بفضل تحسين الفئة الأساسية الفارغة
  • مناسبة جدًا لسياسات التسجيل والمقارنة والعد

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

هل درس «Mixins باستخدام CRTP» مجاني؟

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

ماذا ستتعلم في «Mixins باستخدام CRTP»؟

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

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

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

كم من الوقت يستغرق درس «Mixins باستخدام CRTP»؟

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

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

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

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

  1. أسلوب CRTP
  2. تعدد الأشكال الساكن
  3. Mixins باستخدام CRTP
  4. متى تستخدم CRTP
← العودة إلى C++ Academy