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

نمط المنشئ (Constructor Pattern)

جزء من قسم Object Oriented Programming في رحلة C على Coddy — الدرس 12 من 61.

في لغات مثل Java أو C++، تقوم بإنشاء الكائنات باستخدام المنشئات (constructors)—وهي دوال خاصة تقوم بتخصيص الذاكرة وتهيئة الحقول تلقائيًا. لغة C لا تملك مثل هذه الميزة، ولكن يمكننا محاكاتها بنمط بسيط: دالة create_.

عادةً ما تقوم دالة المنشئ (constructor function) في لغة C بثلاثة أشياء: تخصيص الذاكرة باستخدام malloc، وتهيئة جميع الحقول بالقيم المناسبة، وإرجاع مؤشر (pointer) إلى الكائن الجديد:

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

Person *create_person(const char *name, int age) {
    Person *p = malloc(sizeof(Person));
    p->name = malloc(strlen(name) + 1);
    strcpy(p->name, name);
    p->age = age;
    return p;
}

تُعيد الدالة مؤشرًا لأن الكائن يتواجد في الـ heap، وليس في الـ stack. وهذا يعني أنه يستمر في الوجود بعد انتهاء تنفيذ الدالة ويمكن تمريره بحرية. يستخدمه المستدعي بهذا الشكل:

Person *alice = create_person("Alice", 30);
printf("%s is %d years old\n", alice->name, alice->age);

لاحظ كيف يتعامل الـ constructor مع جميع التفاصيل المعقدة—تخصيص الـ struct، وتخصيص مساحة للـ string، ونسخ البيانات. يقوم المستدعي (caller) فقط بتوفير القيم الأولية ويتلقى كائناً جاهزاً للاستخدام. هذا يغلف منطق الإنشاء في مكان واحد، مما يجعل الكود الخاص بك أكثر نظافة وأقل عرضة للأخطاء.

challenge icon

التحدي

سهل

لنقم ببناء وحدة Book تستخدم نمط المنشئ (constructor pattern) لإنشاء كائنات كتاب في الذاكرة الحيوية (heap). ستتدرب على كتابة دالة create_ تتولى جميع عمليات تخصيص الذاكرة والتهيئة، وتعيد مؤشراً جاهزاً للاستخدام.

ستقوم بإنشاء ثلاثة ملفات:

  • book.h: قم بالتصريح عن هيكل Book يحتوي على عضوين: char *title (مؤشر إلى سلسلة نصية مخصصة ديناميكياً) و int pages. قم أيضاً بالتصريح عن دالة المنشئ create_book التي تأخذ سلسلة نصية للعنوان وعدد الصفحات، ثم تعيد مؤشراً إلى Book تم إنشاؤه حديثاً. استخدم حراس التضمين (include guards) مع الرمز BOOK_H.
  • book.c: قم بتنفيذ دالة create_book. يجب أن يقوم المنشئ الخاص بك بتخصيص ذاكرة لهيكل Book نفسه، ثم تخصيص ذاكرة منفصلة لسلسلة العنوان (تذكر حساب حرف النهاية الصفري null terminator)، ونسخ العنوان إلى الذاكرة الجديدة، وتعيين حقل الصفحات، وإعادة المؤشر إلى Book الجديد.
  • main.c: استخدم المنشئ الخاص بك لإنشاء كتاب وعرض معلوماته.

ستتلقى مدخلين: عنوان الكتاب (سلسلة نصية) و عدد الصفحات (عدد صحيح).

في ملفك الرئيسي، استخدم create_book لإنشاء كتاب جديد بالقيم المقدمة، ثم اطبع معلوماته بهذا التنسيق:

Title: {title}
Pages: {pages}

على سبيل المثال، مع المدخلات The C Programming Language و 272، سيكون الناتج:

Title: The C Programming Language
Pages: 272

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

ورقة مرجعية

تحاكي دالة المنشئ (constructor function) في لغة C عملية إنشاء الكائنات من خلال تخصيص الذاكرة وتهيئة الحقول. وعادةً ما تتبع نمط التسمية create_.

تقوم دالة المنشئ بثلاثة أشياء:

  • تخصيص الذاكرة باستخدام malloc
  • تهيئة جميع الحقول بالقيم المناسبة
  • إرجاع مؤشر (pointer) إلى الكائن الجديد

مثال على نمط المنشئ:

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

Person *create_person(const char *name, int age) {
    Person *p = malloc(sizeof(Person));
    p->name = malloc(strlen(name) + 1);
    strcpy(p->name, name);
    p->age = age;
    return p;
}

استخدام المنشئ:

Person *alice = create_person("Alice", 30);
printf("%s is %d years old\n", alice->name, alice->age);

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

جرّب بنفسك

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

int main() {
    char title[256];
    int pages;
    
    // قراءة المدخلات
    fgets(title, sizeof(title), stdin);
    // إزالة سطر جديد إذا كان موجوداً
    for (int i = 0; title[i]; i++) {
        if (title[i] == '\n') {
            title[i] = '\0';
            break;
        }
    }
    scanf("%d", &pages);
    
    // TODO: استخدم create_book لإنشاء كتاب جديد بالقيم المقدمة
    
    // TODO: اطبع معلومات الكتاب بالتنسيق المطلوب:
    // Title: {title}
    // Pages: {pages}
    
    // TODO: لا تنسَ تحرير الذاكرة المخصصة عند الانتهاء
    
    return 0;
}
quiz iconاختبر نفسك

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

جميع دروس Object Oriented Programming