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

نظرة عامة على المشروع

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

challenge icon

التحدي

سهل

دعنا نضع الأساس لمشروع Shape Drawer من خلال إنشاء هيكل Shape الأساسي — وهو واجهة (interface) تحدد ما يمكن لأي شكل القيام به من خلال مؤشرات الدوال (function pointers).

ستقوم بإنشاء ملفين لإعداد هذا النظام متعدد الأشكال (polymorphic system):

  • shape.h: قم بتعريف الواجهة الأساسية هنا. أولاً، قم بإنشاء إعلان مسبق (forward declaration) لهيكل Shape. ثم قم بتعريف نوعين من مؤشرات الدوال:

    • DrawFunc — يأخذ معامل من نوع const Shape* ولا يعيد شيئاً
    • AreaFunc — يأخذ معامل من نوع const Shape* ويعيد double
    أخيراً، قم بتعريف هيكل Shape نفسه بحيث يحتوي على مؤشري دالة: draw (من نوع DrawFunc) و area (من نوع AreaFunc). يعمل هذا الهيكل كواجهة بحتة — فهو لا يحتوي على بيانات خاصة بالشكل، بل يحتوي فقط على السلوك.
  • main.c: أثبت أن واجهتك تعمل من خلال إنشاء شكل اختبار بسيط. قم بتنفيذ دالتين:
    • test_draw — تطبع Drawing test shape
    • test_area — تعيد 42.0
    قم بإنشاء مثيل (instance) من Shape، وقم بربطه بدوال الاختبار هذه، ثم استدعِ كلتيهما من خلال الواجهة. اطبع نتيجة المساحة بمنزلة عشرية واحدة.

يجب أن يوضح مخرجك أن مؤشرات الدوال تعمل بشكل صحيح:

Drawing test shape
Area: 42.0

لماذا الإعلان المسبق؟ قد تتساءل لماذا يظهر typedef struct Shape Shape; قبل تعريف الهيكل بالكامل. هذا ضروري لأن DrawFunc و AreaFunc يشيران إلى const Shape* في أنواع المعاملات الخاصة بهما — ولكن في تلك النقطة من الملف، لم يكن المترجم (compiler) قد رأى تعريف الهيكل الكامل بعد. يخبر الإعلان المسبق المترجم: "يوجد هيكل باسم Shape"، وهو ما يكفي لاستخدام مؤشر إليه. يتبع ذلك التعريف الكامل لاحقاً. هذا النمط شائع في لغة C كلما احتاج الهيكل إلى الإشارة إلى نفسه (مباشرة أو من خلال مؤشرات الدوال).

الفكرة الأساسية هنا هي أن Shape لا يعرف أي شيء عن الدوائر أو المستطيلات — فهو يعرف فقط أن أي شكل يجب أن يكون قادراً على رسم نفسه (draw) وحساب مساحته (area). في الدروس القادمة، ستنشئ أشكالاً ملموسة تدمج هذا الهيكل الأساسي وتوفر تنفيذاتها الخاصة. تذكر استخدام حراس التضمين (include guards) في ملف الرأس (header file) الخاص بك.

جرّب بنفسك

#include <stdio.h>
#include "shape.h"

// TODO: تنفيذ دالة test_draw
// - تأخذ معامل من نوع const Shape*
// - تطبع "Drawing test shape"
void test_draw(const Shape* shape) {
    // TODO: اطبع الرسالة المطلوبة
}

// TODO: تنفيذ دالة test_area
// - تأخذ معامل من نوع const Shape*
// - تعيد القيمة 42.0
double test_area(const Shape* shape) {
    // TODO: أعد قيمة مساحة الاختبار
}

int main() {
    // TODO: إنشاء مثيل (instance) من Shape
    
    // TODO: ربط الـ shape بدالتي test_draw و test_area
    
    // TODO: استدعاء draw من خلال الواجهة (interface)
    
    // TODO: استدعاء area من خلال الواجهة وطباعتها بمنزلة عشرية واحدة
    // التنسيق: "Area: %.1f\n"
    
    return 0;
}

جميع دروس Object Oriented Programming