لقد رأيت مؤخرًا أحد مستخدمي الإنترنت يسأل على الإنترنت: كيفية تحديد ما إذا كان مؤشر الكائن متاحًا؟ بمعنى آخر، كيفية تحديد ما إذا كان مؤشر الكائن يشير إلى مثيل كائن حقيقي قابل للاستخدام؟ في الواقع هذا لا ينبغي أن يكون مشكلة. لأنه بالنسبة للمبرمج، يجب أن يكون قادرًا على التحكم في برنامجه حتى لا يصل إلى مؤشر غير صالح، لأن إنشاء وتدمير جميع مثيلات الكائن يقع تحت سيطرته. وحتى إذا لم تكن هناك طريقة مباشرة لتحديد ما إذا كان مؤشر الكائن متاحًا، فمن الممكن أيضًا أن يتم ذلك من خلال طرق أخرى غير مباشرة (مثل استخدام بعض المعرفات، وما إلى ذلك) (على سبيل المثال، عندما ندمر مثيل كائن، فإننا نعين مؤشر الكائن هو صفر). لكن إذا وضعنا جانباً النقطتين المذكورتين أعلاه واكتفينا بدراسة ما إذا كانت هناك طريقة لتحديد ما إذا كان مؤشر الكائن متوفراً في دلفي، فماذا سيحدث؟
في Object Pascal، يمكن أن تحتوي الفئة على نوعين من الأساليب، أحدهما يسمى أسلوب الكائن (Object Method) والآخر هو أسلوب الفصل (Class Method). ما يسمى بطريقة الكائن يعني أن تعريف الطريقة مخصص لكائن (أو مثيل)، لذلك يجب أن يعتمد استدعاء الطريقة على كائن (أو مثيل)، على سبيل المثال، تدمير المدمر للفئة هو كائن الطريقة (في الواقع، غالبًا ما تكون معظم الطرق المستخدمة هي طرق كائنية). تشير طريقة الفئة إلى تعريف الطريقة بناءً على فئة من الكائنات، لذلك لا يحتاج استدعاء الطريقة إلى أن يستند إلى مثيل كائن محدد، مثل إنشاء المُنشئ للفئة. هذا لديه بعض الإلهام بالنسبة لنا. يبدو أن تحديد ما إذا كان مؤشر الكائن متاحًا يتم تحقيقه من خلال الخطوات التالية. أولاً، يمكننا تحديد ما إذا كان مؤشر الكائن صفرًا، إذا كان الأمر كذلك، فقد انتهينا وهو بالتأكيد غير متاح، وإذا لم يكن كذلك، فحاول تنفيذ طريقة كائن للكائن لمعرفة ما إذا كانت هناك استثناءات، مثل الوصول غير الصالح إلى الذاكرة. يُستخدم هذا لتحديد ما إذا كان الكائن متاحًا أم لا. استخدم الكود التالي للتحقق من فكرتنا:
فار
Obj: TObject;
يبدأ
Obj:= TObject.Create; //1
Obj.Free; //2. حرر الكائن الذي تم إنشاؤه للتو، ويتم إعادة تدوير الذاكرة في هذا الوقت
إذا كان Obj = nil، فحدد //3 ما إذا كان المؤشر فارغًا (غالبًا ما تكون هذه الخطوة غير ناجحة لأن الكائن
تم تحرير //، ولن تقوم دلفي بإفراغ مؤشر الكائن تلقائيًا)
ShowMessage('مؤشر الكائن غير متوفر.')
آخر
يبدأ
يحاول
إذا كان Obj.ClassType = TObject، فاتصل //4
ShowMessage('نوع الكائن هو TObject');
يستثني
ShowMessage('مؤشر الكائن غير متوفر.')
نهاية؛
نهاية؛
نهاية؛
بتنفيذ الكود أعلاه، نجد أن Obj.ClassType لا يزال متاحًا حتى لو تم تنفيذ Obj.Free. يوضح هذا أنه ليس كل أساليب الكائنات يجب أن تعتمد على مثيل كائن حتى يمكن الوصول إليها. والسبب هو أن طريقة الكائن هذه لا تحتاج إلى الوصول إلى الذاكرة المطلوبة بواسطة مثيل الكائن. وبهذا المعنى، فإن أسلوب TObject.ClassType لا يبدو وكأنه أسلوب كائن حقيقي، ولكنه يشبه أسلوب فئة.
من خلال تنفيذ التعليمات البرمجية أعلاه، يمكننا أيضًا أن نجد أنه عندما ينفذ كائن الطريقة المجانية، فإنه يحرر فقط كل الذاكرة التي تم تطبيقها عليها عند إنشائه، لكنه لا يؤثر على قيمة مؤشر الكائن نفسه. لا يزال مؤشر الكائن يشير إلى عنوان الذاكرة الأصلي. في الوقت نفسه، نظرًا لخصوصية تنفيذ بعض أساليب الكائنات (مثل ClassType)، حتى لو تم إصدار الكائن، فإن نتيجة استدعاء أسلوب الكائن لا تزال صحيحة.
لتلخيص ذلك، يمكننا استخلاص استنتاج، وهو أن ما إذا كان من الممكن الحكم على مؤشر الكائن على أنه متاح يعتمد على ما إذا كانت الفئة التي ينتمي إليها مؤشر الكائن توفر طريقة للوصول إلى ذاكرة مثيل الكائن - يمكن استخدام هذه الطريقة أيضًا تكون خصائص. إذن، ما هو الوضع الآن على وجه التحديد في كل فئة؟
TObject، هذه الفئة هي فئة الأجداد لجميع الفئات، ولا توجد طريقة لإصدار حكم.
لا يحتاج TPersistent، المشتق من TObject، إلى التقدم بطلب للحصول على ذاكرة إضافية عند إنشاء مثيل كائن، لذلك لا توجد طريقة للحكم.
يضيف TComponent، المشتق من TPersistent، العديد من الخصائص التي تتطلب ذاكرة إضافية ليتم تطبيقها عليها عند إنشاء مثيل كائن، لذلك من الناحية النظرية، يتم الحكم عليها. الرمز هو كما يلي:
الدالة ComponentExists(AComponent: TComponent): Boolean;
يبدأ
يحاول
AComponent.Hasparent; // ملاحظة: يمكن أن تكون هذه الجملة أيضًا "AComponent.Tag;"
// أو "اسم المكون"
النتيجة := صحيح؛
يستثني
النتيجة:= خطأ؛
نهاية؛
نهاية؛
من خلال استدعاء ComponentExists، يمكننا معرفة ما إذا كان مؤشر الكائن من النوع TComponent متاحًا، بغض النظر عما إذا كان مؤشر الكائن قد تم تحريره أو ضبطه على الصفر.
بالنسبة للفئات الأخرى، مثل TControl أو TWinControl أو TButton وما إلى ذلك، طالما أنها مشتقة من TComponent، فإن طريقة الحكم الخاصة بـ TComponent لا تزال سارية.
هناك فئات أخرى محددة من قبل المستخدم، إذا كانت مشتقة مباشرة من الفئات التي لا يمكن الحكم عليها (مثل TObject وTPersistent)، ولكن لا توجد سمات تتطلب تطبيق الذاكرة أثناء إنشاء مثيل، فلا توجد طريقة للحكم عليها؛ ممكن. وفقا لمثال:
لنفترض أن لدينا فئة TPerson محددة على النحو التالي:
TPerson = الفئة (TObject)
خاص
FSex: TSex؛ // TSex هو جنس نوع التعداد؛
الاسم الأول: سلسلة؛
اسم العائلة: سلسلة؛
//...
عام
خاصية الجنس: TSex قراءة FSex كتابة FSex؛
الخاصية الاسم الأول: سلسلة قراءة FFirstName كتابة FFirstName؛
الخاصية اسم العائلة: سلسلة قراءة FLastName كتابة FLastName؛
//...
نهاية؛
بعد ذلك، بالنسبة للمؤشر شخص من النوع TPerson، يمكنك استخدام التعليمات البرمجية التالية لتحديد ما إذا كان المؤشر متاحًا:
يحاول
شخص.الجنس؛
//أو الشخص.الاسم الأول؛
// أو Person.LastName؛
النتيجة := صحيح؛ // المؤشر متاح
يستثني
النتيجة := خطأ؛// المؤشر غير متوفر
نهاية؛
ما ناقشناه أعلاه هو مجرد احتمال تقني. النقطة التي أريد التأكيد عليها هي أنه حتى لو كانت هناك طريقة جيدة للقيام بذلك، فلا يتم تشجيعها على القيام بذلك بشكل متكرر. لأن البرنامج ذو المنطق الصارم يجب أن يكون قادرًا على منع الوصول إلى مؤشر غير صالح.
المزيد من المقالات