Menu
Coddy logo textTech
flag Ar iconالعربيةdown icon

نمط الهادم (Destructor Pattern)

جزء من قسم البرمجة كائنية التوجه في رحلة C على Coddy. الدرس 13 من 61.

يجب في النهاية تحرير كل كائن تم إنشاؤه باستخدام malloc. وكما كتبنا دالة create_ للتعامل مع التخصيص، نكتب دالة free_ للتعامل مع التنظيف. يُسمّى هذا نمط المُدمّر.

الفكرة الأساسية هي أن عملية التحرير يجب أن تحدث بالترتيب العكسي لـ allocation. إذا كان constructor قد خصص internal members أولًا ثم البنية نفسها، فيجب على destructor أن يحرر members البنية أولًا، ثم البنية نفسها:

typedef struct {
    char *name;
    int age;
} Person;

void free_person(Person *p) {
    if (p == NULL) return;  // فحص السلامة
    free(p->name);          // حرر العضو الداخلي أولاً
    free(p);                // ثم حرر الـ struct نفسه
}

يمنع check الخاص بـ NULL في البداية حدوث الأعطال إذا مرّر أحدهم مؤشّرًا غير صالح عن طريق الخطأ. بعد تحرير سلسلة name ‏internal، نقوم بتحرير البنية نفسها. إذا قمنا بتحرير p أولًا، فسوف نفقد الوصول إلى p->name ونتسبب في تسرّب في الذاكرة.

استخدام destructor أمر مباشر:

Person *alice = create_person("Alice", 30);
// ... استخدم alice ...
free_person(alice);  // نظّف عند الانتهاء

يضمن هذا النمط تحرير كل memory بشكل صحيح. وبدونه، سيسرّب كل كائن تنشئه memory حتى تنفد من برنامجك.

challenge icon

التحدي

سهل

لنَبْنِ وحدة Movie توضّح دورة حياة الكائن كاملةً: الإنشاء والتدمير معًا. ستتدرّب على كتابة دالة destructor تنظّف جميع الذاكرة allocated بالترتيب الصحيح.

ستنشئ ثلاثة ملفات:

  • movie.h: Declare بنية Movie تحتوي على عضوين: char *title (سلسلة نصية allocated dynamically) وint year. Declare كلًا من constructor create_movie الذي يستقبل title وyear، وdestructor free_movie الذي يستقبل مؤشرًا إلى Movie. استخدم include guards بالرمز MOVIE_H.
  • movie.c: Implement كلتا الدالتين. يجب أن يخصص constructor ذاكرة للبنية ولسلسلة title (لا forget null terminator). يجب أن يحرر destructor الذاكرة بترتيب عكسي للتخصيص: أولًا سلسلة title الداخلية، ثم البنية نفسها. أضف NULL check في بداية destructor لضمان الأمان.
  • main.c: أنشئ movie، واعرض information الخاصة به، ثم نظّف الذاكرة بشكل صحيح.

ستتلقى inputين: عنوان movie (سلسلة نصية) وسنة الإصدار (عدد صحيح).

في ملف main، استخدم create_movie لإنشاء movie جديد، واطبع information الخاصة به، ثم استدعِ free_movie لتحرير كل الذاكرة. بعد التحرير، اطبع رسالة تأكيد.

اطبع output بهذا format:

Movie: {title} ({year})
Memory freed

على سبيل المثال، عند استخدام inputين Inception و2010، سيكون output كما يلي:

Movie: Inception (2010)
Memory freed

تذكّر: المفتاح إلى destructor سليم هو التحرير بالترتيب العكسي. كل ما يخصصه constructor أولًا يتم تحريره أخيرًا، وكل ما يخصصه أخيرًا يتم تحريره أولًا.

جرّب بنفسك

#include <stdio.h>
#include <stdlib.h>
#include "movie.h"

int main() {
    char title[100];
    int year;
    
    // اقرأ الإدخال
    scanf("%[^\n]", title);
    scanf("%d", &year);
    
    // TODO: أنشئ فيلمًا باستخدام create_movie
    
    // TODO: اطبع معلومات الفيلم بالصيغة:
    // فيلم: {title} ({year})
    
    // TODO: حرّر الفيلم باستخدام free_movie
    
    // TODO: اطبع "Memory freed"
    
    return 0;
}
quiz iconاختبر نفسك

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

جميع دروس البرمجة كائنية التوجه

تدرّب بنفسك: مترجم C عبر الإنترنت