الـ Structs ككائنات
جزء من قسم البرمجة كائنية التوجه في رحلة C على Coddy. الدرس 6 من 61.
في اللغات كائنية التوجه، الكائن هو كيان يجمع البيانات (الحالة) مع الدوال التي تعمل على تلك البيانات (الأساليب). لا تحتوي لغة C على كائنات مدمجة، لكن يمكننا تحقيق المفهوم نفسه باستخدام البُنى والدوال.
فكّر في struct باعتباره جزء "البيانات" من الكائن. فهو يحتفظ بالحالة: القيم التي تحدد ماهية الكائن حاليًا:
typedef struct {
int value;
} Counter;
يمثل هذا الهيكل Counter كيانًا ذا حالة واحدة: قيمته الحالية. ولإضافة سلوك إليه، نكتب دوالًا تقبل الهيكل كمعامل:
void counter_increment(Counter *c) {
c->value++;
}
int counter_get(Counter *c) {
return c->value;
}
تعمل هذه الدوال مثل الأساليب. وهي تعمل تحديدًا على بيانات Counter. ومن خلال تمرير struct إلى الدوال، نحاكي ما تفعله اللغات الأخرى تلقائيًا عند استدعاء counter.increment().
int main() {
Counter my_counter = {0};
counter_increment(&my_counter);
printf("%d\n", counter_get(&my_counter)); // يطبع: 1
return 0;
}
تساعد اصطلاحية التسمية typename_action (مثل counter_increment) في تنظيم التعليمات البرمجية وتجعل من الواضح إلى أي struct تنتمي الدالة. يشكّل هذا النمط أساس البرمجة كائنية التوجه في C.
التحدي
سهللنبنِ وحدة Counter بسيطة تتعامل مع البنية ككائن ذي سلوك. ستنظّم التعليمات البرمجية عبر ثلاثة ملفات للتدرّب على نمط تجميع البيانات مع functions التي تعمل عليها.
ستنشئ ثلاثة ملفات:
counter.h: ملف الرأس الذي يعلن عن بنيةCounterذات single عضوint value. أعلن أيضًا عن دالتين تعملان بوصفهما «أساليب» للعداد:counter_increment(takes مؤشرًا إلى Counter وincreases قيمته بمقدار 1) وcounter_get(takes مؤشرًا إلى Counter وreturns قيمته current). استخدم include guards بالرمزCOUNTER_H.counter.c: ملف المصدر الذي يطبّق الدالتين كلتيهما. تذكّر تضمين ملف الرأس.main.c: ملف main الذي ينشئ Counter، وينفّذ العمليات عليه، ويعرض النتائج.
ستتلقى مدخلين صحيحين: قيمة البدء للعداد وعدد المرات التي يجب زيادته فيها.
في ملف main، initialize قيمة Counter بقيمة البدء، ثم استدعِ counter_increment بالعدد specified من المرات. أخيرًا، استخدم counter_get لاسترداد القيمة النهائية وطباعتها.
اطبع result بهذا التنسيق:
Final value: {result}على سبيل المثال، عند استخدام قيمة بدء تساوي 5 و3 زيادات، سيكون الناتج:
Final value: 8جرّب بنفسك
#include <stdio.h>
#include "counter.h"
int main() {
// اقرأ المدخلات
int starting_value;
int num_increments;
scanf("%d", &starting_value);
scanf("%d", &num_increments);
// TODO: أنشئ Counter وقم بتهيئته باستخدام starting_value
// TODO: استدعِ counter_increment العدد المحدد من المرات
// TODO: استخدم counter_get لاسترجاع القيمة النهائية وطباعتها
// صيغة الطباعة: "Final value: {result}"
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 عبر الإنترنت