حاوية الأشكال
جزء من قسم البرمجة كائنية التوجه في رحلة C على Coddy. الدرس 48 من 61.
التحدي
سهللنصل بمشروع Shape Drawer إلى خاتمته الكبرى! ستنشئ حاوية للأشكال تحتوي على مجموعة مختلطة من Circles وRectangles، ثم تتكرر خلالها لحساب المساحة الإجمالية، موضحًا القوة الحقيقية لتعدد الأشكال.
بناءً على كل ما أنشأته حتى الآن، سيتضمن مشروعك الكامل ما يلي:
shape.hوshape.c: واجهة Shape الأساسية ودالةprocess_shape.circle.hوcircle.c: تطبيق Circle مع المُنشئ الخاص به وحساب المساحة.rectangle.hوrectangle.c: تطبيق Rectangle مع المُنشئ الخاص به وحساب المساحة.main.c: هنا تحدث الأمور الرائعة. ستنشئ مصفوفة من مؤشراتShape*يمكنها الاحتفاظ بأي نوع من الأشكال. املأها بمزيج من Circles وRectangles، ثم مرّر عبر المصفوفة لحساب وعرض المساحة الإجمالية لجميع الأشكال مجتمعة.
سيستقبل برنامجك المدخلات التالية:
- عدد الأشكال المطلوب إنشاؤها
- لكل شكل: مؤشر نوع (
cللدائرة، وrللمستطيل) متبوعًا بأبعاده
لكل شكل في حاويتك، استدعِ draw وarea بنفسك من خلال مؤشر Shape* (shapes[i]->draw(shapes[i])، shapes[i]->area(shapes[i])) وأضف المساحة إلى إجمالي جارٍ. لا تستخدم process_shape من shape.c هنا: فهي تطبع سطر Area: إضافيًا لكل شكل، وهو ما لا يتضمنه الناتج المتوقع. بعد معالجة جميع الأشكال، اطبع المساحة الإجمالية بمنزلتين عشريتين بالتنسيق Total Area: X.XX.
مثال باستخدام المدخلات 3، ثم c 5.0، وr 4.0 3.0، وc 2.0:
Drawing Circle with radius: 5.00
Drawing Rectangle with width: 4.00 and height: 3.00
Drawing Circle with radius: 2.00
Total Area: 103.11مثال باستخدام المدخلات 2، ثم r 6.0 4.0، وr 3.0 2.0:
Drawing Rectangle with width: 6.00 and height: 4.00
Drawing Rectangle with width: 3.00 and height: 2.00
Total Area: 30.00الفكرة الأساسية هي أن مصفوفتك تخزن مؤشرات Shape*. وهي لا تهتم بما إذا كان كل عنصر Circle أو Rectangle فعليًا. عند التكرار واستدعاء draw وarea من خلال كل مؤشر، يُنفَّذ التطبيق الصحيح تلقائيًا استنادًا إلى كيفية إنشاء كل شكل. هذا هو تعدد الأشكال أثناء العمل: حلقة واحدة، وواجهة واحدة، وسلوكيات متعددة.
تذكر أنك ستحتاج إلى تخزين مؤشرات إلى أعضاء Shape المضمّنة في أشكالك الملموسة داخل المصفوفة. استخدم 3.14159 لقيمة π في حسابات مساحة الدائرة.
مهم: قراءة محرف نوع الشكل: بعد قراءة عدد الأشكال باستخدام scanf("%d", &n)، يجب أن تتخطى كل استدعاءات قراءة محرف النوع اللاحقة محرف السطر الجديد المتبقي في مخزن الإدخال المؤقت. استخدم مسافة بادئة في سلسلة التنسيق للقيام بذلك:
scanf(" %c", &type); // note the space before %cمن دون المسافة البادئة، ستقرأ scanf محرف السطر الجديد المتبقي من الإدخال السابق بدلًا من c أو r المقصود، مما يؤدي إلى فشل فحص نوع الشكل بصمت وعدم إنتاج أي مخرجات.
جرّب بنفسك
#include <stdio.h>
#include <stdlib.h>
#include "shape.h"
#include "circle.h"
#include "rectangle.h"
int main() {
// TODO: اقرأ عدد الأشكال
// TODO: خصّص مصفوفات للدوائر والمستطيلات ومؤشرات Shape*
// TODO: مرّ على كل شكل، اقرأ نوعه وأبعاده،
// أنشئ الشكل، واحفظ مؤشراً إلى قاعدته في مصفوفة shapes
// TODO: مرّ على مصفوفة shapes، استدعِ shapes[i]->draw(...) و
// shapes[i]->area(...) مباشرة وراكم المساحة الإجمالية
// (لا تستدعِ process_shape: فهو يطبع سطراً إضافياً Area)
// TODO: اطبع المساحة الإجمالية بالصيغة: Total Area: X.XX
// TODO: حرّر الذاكرة المخصصة
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 عبر الإنترنت