نظرة عامة على المشروع
جزء من قسم البرمجة كائنية التوجه في رحلة C على Coddy. الدرس 44 من 61.
التحدي
سهللنضع الأساس لمشروع Shape Drawer من خلال إنشاء Shape struct الأساسي: واجهة تحدد ما يمكن لأي شكل القيام به عبر مؤشرات إلى functions.
ستنشئ ملفين لإعداد هذا النظام متعدد الأشكال:
shape.h: عرّف الواجهة الأساسية هنا. أولًا، أنشئ forward declaration لـShapestruct. ثم عرّف نوعين من مؤشرات functions:DrawFunc: يأخذconst Shape*parameter ولا يعيد شيئًاAreaFunc: يأخذconst Shape*parameter ويعيدdouble
Shapestruct نفسه، بحيث يحتوي على مؤشري functions:draw(من النوعDrawFunc) وarea(من النوعAreaFunc). يعمل هذا struct كواجهة فقط. فهو لا يحتوي على أي بيانات خاصة بالشكل، بل على السلوك فقط.main.c: أثبت أن واجهتك تعمل من خلال إنشاء شكل اختبار بسيط. Implement دالتين:test_draw: تطبعDrawing test shapetest_area: تعيد42.0
Shape، واربطه بـ test functions هذه، ثم استدعِ كليهما عبر الواجهة. اطبع نتيجة area بمنزلة عشرية واحدة.
يجب أن يوضح ناتجك أن مؤشرات functions تعمل بشكل صحيح:
Drawing test shape
Area: 42.0لماذا نحتاج إلى forward declaration؟ قد تتساءل عن سبب ظهور typedef struct Shape Shape; قبل تعريف struct بالكامل. هذا ضروري لأن DrawFunc وAreaFunc يشيران إلى const Shape* في أنواع parameter الخاصة بهما، ولكن في تلك النقطة من الملف، لم يرَ compiler تعريف struct الكامل بعد. يخبر forward declaration الـ compiler بأن: "a struct named Shape exists"، وهذا يكفي لاستخدام pointer إليه. يأتي التعريف الكامل لاحقًا. هذا النمط شائع في C عندما يحتاج struct إلى الإشارة إلى نفسه، سواء مباشرةً أو عبر مؤشرات functions.
الفكرة الأساسية هنا هي أن Shape لا يعرف أي شيء عن الدوائر أو المستطيلات. إنه يعرف فقط أن أي شكل يجب أن يكون قادرًا على draw نفسه وحساب area الخاصة به. في الدروس القادمة، ستنشئ أشكالًا ملموسة تدمج هذا struct الأساسي وتوفر Implement الخاصة بها. تذكّر استخدام include guards في ملف الرأس الخاص بك.
جرّب بنفسك
#include <stdio.h>
#include "shape.h"
// TODO: نفّذ دالة test_draw
// - تأخذ معامل const Shape*
// - Prints "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: أنشئ نسخة من Shape
// TODO: اربط الشكل بدالتي test_draw و test_area
// TODO: استدعِ draw عبر الواجهة
// TODO: استدعِ area عبر الواجهة واطبع بقيمة عشرية واحدة
// التنسيق: "Area: %.1f\n"
return 0;
}
جميع دروس البرمجة كائنية التوجه
1أساسيات البرمجة التركيبية
ملفات الترويسةحواجز التضمينملفات المصدرالدوال الساكنةمراجعة: آلة حاسبة تركيبية4التغليف (Encapsulation)
مفهوم الـ Opaque Pointersتعريف الـ Opaque Structsالـ Getters والـ Settersالتحقق من البيانات في الـ Settersملخص: الصندوق السري2الكائنات والأساليب
الـ Structs ككائناتمؤشر 'Self'صحة استخدام Constالمؤشر مقابل القيمةالأساليب المساعدةملخص: Point Manager5مشروع: حساب بنكي بسيط
إعداد المشروعتنفيذ الحساب3دورة حياة الكائن
نمط المنشئ (Constructor Pattern)نمط الهادم (Destructor Pattern)تهيئة الـ Stackالنسخ العميق (Deep Copy)مراجعة: String Wrapper6الوراثة عبر التركيب
تضمين الـ Structقاعدة العضو الأولالوصول إلى أعضاء الأبعملية الـ Upcastingمراجعة: هرمية الأشكال9مشروع: رسّام الأشكال
نظرة عامة على المشروعتنفيذ الدائرةتنفيذ المستطيلاستخدام تعدد الأشكالحاوية الأشكالتدرّب بنفسك: مترجم C عبر الإنترنت