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

الـ Getters والـ Setters

جزء من قسم البرمجة كائنية التوجه في رحلة C على Coddy. الدرس 19 من 61.

باستخدام المؤشرات opaque، تكون أعضاء البنية مخفية عن التعليمات البرمجية الخارجية. ولكن إذا لم تتمكن التعليمات البرمجية الخارجية من الوصول إلى البيانات مباشرةً، فكيف نقرأها أو نعدّلها؟ الإجابة هي دوال getter وsetter: واجهات عامة توفّر وصولًا متحكمًا به إلى البيانات الخاصة.

تعيد getter قيمة عضو مخفي:

// counter.h
int counter_get_value(const Counter *c);

// counter.c
int counter_get_value(const Counter *c) {
    return c->value;
}

تعدّل دالة setter عضوًا مخفيًا:

// counter.h
void counter_set_value(Counter *c, int new_value);

// counter.c
void counter_set_value(Counter *c, int new_value) {
    c->value = new_value;
}

لاحظ اصطلاح التسمية: ابدأ أسماء الدوال باسم النوع (counter_) لتجنب التعارضات وجعل واجهة API واضحة. تستخدم دوال getter مؤشرات const لأنها لا تعدّل الكائن.

الآن يمكن للتعليمات البرمجية الخارجية التفاعل مع البيانات المخفية بأمان:

// main.c
Counter *c = create_counter(10);
printf("%d\n", counter_get_value(c));  // 10
counter_set_value(c, 25);
printf("%d\n", counter_get_value(c));  // 25

يمنحك هذا النمط تحكمًا كاملًا في كيفية الوصول إلى البيانات: وهو أساس سنبني عليه في الدرس التالي عندما نضيف منطق التحقق إلى دوال setter.

challenge icon

التحدي

سهل

لنبنِ وحدة Score تستخدم نمط المؤشر المعتم مع دوال getter وsetter. ستنشئ متتبّعًا مخفيًا للنتيجة، حيث لا يستطيع الكود الخارجي التفاعل مع البيانات إلا من خلال الواجهة العامة التي توفّرها.

ستنشئ ثلاثة ملفات:

  • score.h: واجهتك العامة. أعلن عن نوع Score معتم باستخدام إعلان أمامي (من دون جسم البنية!). أعلن عن هذه الدوال:
    • create_score: يأخذ قيمة integer لـ initial points ويعيد مؤشر Score
    • free_score: يأخذ مؤشر Score ويحرّر memory
    • score_get_points: دالة getter تأخذ const Score * وتعيد قيمة points الحالية
    • score_set_points: دالة setter تأخذ Score * وinteger، وتحدّث قيمة points
    استخدم حواجز التضمين بالرمز SCORE_H.
  • score.c: عرّف struct Score الفعلية مع member مخفي واحد: int points. نفّذ الدوال الأربع جميعها. يجب أن يعيد getter القيمة المخفية، وأن يحدّث setter هذه القيمة. تذكّر أن دوال getter تستخدم مؤشرات const لأنها لا تعدّل الكائن.
  • main.c: اعرض كيفية استخدام وحدتك من خلال إنشاء score، وقراءة قيمته، وتعديله عبر setter، ثم قراءته مرة أخرى.

ستتلقى مُدخلين: initial points (قيمة integer) وقيمة new points (قيمة integer) لتعيينها.

في ملفك الرئيسي، أنشئ Score باستخدام initial points، واطبع القيمة الحالية باستخدام getter، ثم حدّثها باستخدام setter مع القيمة الجديدة، واطبع القيمة المحدّثة، ثم حرّر score واطبع تأكيدًا.

اطبع الناتج بهذا التنسيق:

Initial: {points}
Updated: {points}
Freed

على سبيل المثال، عند استخدام المُدخلين 100 و250، سيكون الناتج:

Initial: 100
Updated: 250
Freed

لاحظ أن main.c لا يستطيع الوصول إلى points مباشرةً. يجب أن يمر عبر دوال getter وsetter الخاصة بك. هذا هو مبدأ التغليف أثناء العمل: فأنت تتحكم بدقة في كيفية قراءة البيانات المخفية وتعديلها.

جرّب بنفسك

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

int main() {
    int initial_points, new_points;
    scanf("%d", &initial_points);
    scanf("%d", &new_points);
    
    // TODO: أنشئ Score باستخدام initial_points
    
    // TODO: اطبع القيمة الأولية باستخدام الـ getter
    // التنسيق: "Initial: {points}"
    
    // TODO: حدّث الـ score باستخدام الـ setter مع new_points
    
    // TODO: اطبع القيمة المحدّثة باستخدام الـ getter
    // التنسيق: "Updated: {points}"
    
    // TODO: حرّر الـ score واطبع "Freed"
    
    return 0;
}
quiz iconاختبر نفسك

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

جميع دروس البرمجة كائنية التوجه

تدرّب بنفسك: مترجم C عبر الإنترنت