0Pricing
C++ Academy · درس

قاعدة الثلاثة/الخمسة

أدر النسخ والنقل بطريقة صحيحة

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

قاعدة الثلاثة

إذا احتاج صنف إلى مدمر مخصص، فهو يحتاج في الغالب أيضًا إلى منشئ نسخ مخصص ومعامل إسناد نسخ مخصص. وهذه العناصر الثلاثة تأتي معًا.

لماذا ثلاثة؟

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

#include <iostream>

class Bad {
    int* p;
public:
    Bad(int v) : p(new int(v)) {}
    ~Bad() { delete p; }
    // default copy => two objects delete the same p!
};

منشئ نسخ مخصص

ينفّذ منشئ النسخ الصحيح نسخًا عميقًا، فيخصّص مورده الخاص بدلًا من مشاركته.

#include <iostream>

class Box {
    int* p;
public:
    Box(int v) : p(new int(v)) {}
    Box(const Box& o) : p(new int(*o.p)) {}   // deep copy
    ~Box() { delete p; }
    int get() const { return *p; }
};

int main() {
    Box a(5);
    Box b = a;   // independent copy
    std::cout << b.get() << "\n";
}

إسناد نسخ مخصص

يجب أن يحرّر إسناد النسخ المورد القديم، ويتحقق من الإسناد الذاتي، وينسخ القيمة الجديدة نسخًا عميقًا.

Box& operator=(const Box& o) {
    if (this != &o) {              // self-assignment guard
        delete p;
        p = new int(*o.p);
    }
    return *this;
}

قاعدة الخمسة

أضاف C++11 عمليات النقل. إذا عرّفت أيًا من العناصر الخمسة (المُخرّب، ومنشئ النسخ، وإسناد النسخ، ومنشئ النقل، وإسناد النقل)، ففكّر في تعريفها كلها.

منشئ النقل

يسرق منشئ النقل المورد من كائن مؤقت ويترك المصدر فارغًا — وهذا أقل تكلفة بكثير من النسخ.

Box(Box&& o) noexcept : p(o.p) {
    o.p = nullptr;   // source left empty
}

إسناد النقل

يحرّر إسناد النقل المورد الحالي، ثم يستولي على ملكية مورد المصدر.

Box& operator=(Box&& o) noexcept {
    if (this != &o) {
        delete p;
        p = o.p;
        o.p = nullptr;
    }
    return *this;
}

وضع وسم noexcept لعمليات النقل

يجب أن تكون عمليات النقل noexcept حتى تتمكن الحاويات مثل std::vector من استخدامها بأمان عند إعادة التخصيص.

قاعدة الصفر

والأفضل من ذلك كله: لا تملك موردًا خامًا. استخدم std::unique_ptr أو std::vector أو std::string، وعندها لن تحتاج إلى تعريف أي من العناصر الخمسة — فالإعدادات الافتراضية للمصرّف صحيحة.

#include <memory>

class Good {
    std::unique_ptr<int> p;   // owns the resource for you
public:
    Good(int v) : p(std::make_unique<int>(v)) {}
    // no destructor, no copy/move needed
};

حذف العمليات

إذا لم يكن للنسخ معنى، فاحذفه: Box(const Box&) = delete;. وهكذا يصبح النوع قابلًا للنقل فقط أو غير قابل للنسخ عمدًا.

اختيار القاعدة المناسبة

استهدف قاعدة الصفر. ولا تلجأ إلى قاعدة الخمسة إلا عندما تغلّف فعليًا موردًا خامًا لا تغطيه المكتبة القياسية.

تحقق سريع

اختبر فهمك لقاعدة الثلاثة/الخمسة.

مراجعة

تعلّمت قاعدة الثلاثة/الخمسة: إن إدارة مورد خام تعني تعريف المُخرّب وعمليات النسخ والنقل باتساق. ضع وسم noexcept لعمليات النقل. والأفضل من ذلك كله، اتبع قاعدة الصفر باستخدام أنواع RAII القياسية وعدم تعريف أي منها.

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

هل درس «قاعدة الثلاثة/الخمسة» مجاني؟

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

ماذا ستتعلم في «قاعدة الثلاثة/الخمسة»؟

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

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

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

كم من الوقت يستغرق درس «قاعدة الثلاثة/الخمسة»؟

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

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

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

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

  1. مبدأ RAII
  2. المُدمّرات والتنظيف
  3. قاعدة الثلاثة/الخمسة
  4. حُرّاس النطاق
← العودة إلى C++ Academy