مفهوم الـ Opaque Pointers
جزء من قسم Object Oriented Programming في رحلة C على Coddy — الدرس 17 من 61.
حتى الآن، عندما نقوم بتعريف struct في ملف رأس (header file)، يمكن لأي شخص يقوم بتضمين ذلك الرأس رؤية جميع أعضائه والوصول إليها مباشرة. هذا يكسر مبدأ التغليف (encapsulation) — وهو المبدأ القائل بإخفاء التفاصيل الداخلية عن الكود الخارجي.
توفر لغة C تقنية قوية تسمى المؤشرات غير الشفافة (opaque pointers) لحل هذه المشكلة. الفكرة بسيطة: صرّح بأن الـ struct موجود في ملف الرأس (header)، ولكن لا تكشف عما بداخله. يتم ذلك باستخدام نوع غير مكتمل (incomplete type):
// wallet.h
typedef struct Wallet Wallet; // تصريح فقط - بدون محتوى!
Wallet *create_wallet(int initial_balance);
void free_wallet(Wallet *w);
لاحظ عدم وجود أقواس متعرجة - فنحن لا نحدد أبدًا ما يحتويه Wallet. يعرف المترجم أن النوع موجود، ولكن ليس حجمه أو أعضاءه. وهذا يعني أن الكود الذي يتضمن هذا الـ header لا يمكنه العمل إلا مع مؤشرات (pointers) إلى Wallet، وليس مع الـ struct نفسه مباشرةً.
لماذا يهم هذا؟ لأن تعريف الـ struct الفعلي يظل مخفياً في ملف الـ .c، فإن أي كود يستخدم ملف الترويسة (header) الخاص بك لا يمكنه كتابة w->balance أو sizeof(Wallet). يجب عليهم استخدام الدوال التي توفرها. أنت تتحكم في كل عمليات الوصول إلى البيانات، ويمكنك تغيير الهيكل الداخلي لاحقاً دون كسر أي كود يعتمد على ملف الترويسة الخاص بك.
في الدرس القادم، ستتدرب على تعريف جسم الـ struct الفعلي داخل ملف المصدر، مكملاً بذلك نمط المؤشر المعتم (opaque pointer pattern).
ورقة مرجعية
يستخدم المؤشر المبهم (opaque pointer) نوعاً غير مكتمل لإخفاء تفاصيل تنفيذ الهيكل (struct)، مما يفرض مبدأ التغليف (encapsulation).
صرّح عن الهيكل في ملف الترويسة (header) دون تحديد جسمه:
// wallet.h
typedef struct Wallet Wallet; // تصريح فقط - بدون أقواس متعرجة
Wallet *create_wallet(int initial_balance);
void free_wallet(Wallet *w);
يعرف المترجم (compiler) بوجود النوع ولكن ليس حجمه أو أعضاءه. يمكن للمستخدمين العمل فقط مع مؤشرات للهيكل ويجب عليهم استخدام الدوال المقدمة للتفاعل معه.
يتم وضع تعريف الهيكل الفعلي في ملف .c، مما يمنع الوصول المباشر للأعضاء مثل w->balance أو استخدام sizeof(Wallet).
جرّب بنفسك
لا يتضمّن هذا الدرس تحدّيًا برمجيًا.
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس Object Oriented Programming
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مشروع: رسّام الأشكال
نظرة عامة على المشروعتنفيذ الدائرة