مؤشرات أو مؤشرات ذكية أو مؤشرات مشتركة؟ [مكرر

StackOverflow https://stackoverflow.com/questions/417481

  •  03-07-2019
  •  | 
  •  

سؤال

هذا السؤال لديه بالفعل إجابة هنا:

أقوم برمجة مع مؤشرات عادية ، لكنني سمعت عن مكتبات مثل Boost التي تنفذ المؤشرات الذكية. لقد رأيت أيضًا أنه في محرك تقديم OGRE3D هناك استخدام عميق للمؤشرات المشتركة.

ما هو بالضبط الفرق بين الثلاثة ، وهل يجب أن ألتزم باستخدام نوع منها فقط؟

هل كانت مفيدة؟

المحلول

أوضحت سيدوس الأنواع بشكل جيد إلى حد ما:

  • المؤشرات العادية هي فقط - أنها تشير إلى شيء ما في الذاكرة في مكان ما. من يمتلكه؟ فقط التعليقات سوف تخبرك. من يحررها؟ نأمل المالك في مرحلة ما.
  • مؤشرات ذكية هي مصطلح بطاني يغطي العديد من الأنواع ؛ سأفترض أنك تعني مؤشر النطاق الذي يستخدم راي نمط. إنه كائن مُصلح المكدس يلف مؤشرًا ؛ عندما يخرج من النطاق ، فإنه يدعو إلى حذف المؤشر الذي يلفه. "يمتلك" المؤشر المحتوى من حيث أنه مسؤول عن حذفه في مرحلة ما. إنها تتيح لك الحصول على إشارة خام إلى المؤشر الذي يلفونه لتمريره إلى طرق أخرى ، وكذلك إطلاق المؤشر ، مما يسمح لشخص آخر بامتلاكه. نسخهم لا معنى له.
  • مؤشرات مشتركة هو كائن محدد المكدس يلف مؤشرًا بحيث لا يتعين عليك معرفة من يملكه. عندما يتم تدمير آخر مؤشر مشترك لكائن في الذاكرة ، سيتم أيضًا حذف المؤشر ملفوف.

ماذا عن متى يجب أن تستخدمها؟ ستقوم إما بالاستفادة الكثيفة من المؤشرات الناطمية أو المؤشرات المشتركة. كم عدد المواضيع التي يتم تشغيلها في التطبيق الخاص بك؟ إذا كانت الإجابة "من المحتمل أن تكون كثيرًا" ، فيمكن أن تكون المؤشرات المشتركة عنق الزجاجة الأداء إذا تم استخدامها في كل مكان. السبب في أن إنشاء/نسخ/تدمير مؤشر مشترك يجب أن يكون عملية ذرية ، وهذا يمكن أن يعيق الأداء إذا كان لديك العديد من المواضيع. ومع ذلك ، لن يكون هذا هو الحال دائمًا - فقط الاختبار سيخبرك بالتأكيد.

هناك حجة (أحبها) ضد المؤشرات المشتركة - باستخدامها ، فأنت تسمح للمبرمجين بتجاهل من يملك مؤشرًا. يمكن أن يؤدي ذلك إلى مواقف صعبة مع مراجع دائرية (ستكتشف Java هذه ، لكن لا يمكن للمؤشرات المشتركة) أو كسل المبرمج العام في قاعدة كود كبيرة.

هناك سببان لاستخدام مؤشرات النطاق. الأول هو لعمليات السلامة والتنظيف الاستثناء البسيط - إذا كنت تريد أن تضمن تنظيف كائن بغض النظر عن ما في مواجهة الاستثناءات ، ولا تريد تخصيص هذا الكائن ، فضعه في مؤشر محدد. إذا كانت العملية نجاحًا ، فيمكنك أن تتردد في نقلها إلى مؤشر مشترك ، ولكن في الوقت نفسه ، احفظ النفقات العامة مع مؤشر النطاق.

الحالة الأخرى هي عندما تريد ملكية كائن واضحة. بعض الفرق تفضل هذا ، بعضها لا. على سبيل المثال ، قد تُرجع بنية البيانات مؤشرات إلى كائنات داخلية. تحت مؤشر النطاق ، فإنه سيعيد مؤشرًا أو مرجعًا خامًا يجب معاملته كمرجع ضعيف - إنه خطأ في الوصول إلى هذا المؤشر بعد بنية البيانات التي تملكها ، وهو خطأ في حذفه. بموجب مؤشر مشترك ، لا يمكن للكائن المملوك أن يدمر البيانات الداخلية التي تم إرجاعها إذا كان شخص ما لا يزال يحمل مقبضًا عليه - قد يترك هذا الموارد مفتوحة لفترة أطول من اللازم ، أو أسوأ بكثير اعتمادًا على الرمز.

نصائح أخرى

مصطلح "المؤشر الذكي" يشمل المؤشرات المشتركة ، مؤشرات السيارات ، قفل المؤشرات وغيرها. كنت تقصد أن تقول المؤشر التلقائي (المعروف بشكل أكثر غموضًا باسم "امتلاك المؤشر") ، وليس مؤشرًا ذكيًا.

المؤشرات الغبية (T*) ليست أفضل حل. إنها تجعلك تقوم بإدارة الذاكرة الصريحة ، وهي مطوّلة ، وعرضة للخطأ ، وأحيانًا مستحيلة. ولكن الأهم من ذلك ، أنها لا تشير إلى نيتك.

مؤشرات السيارات تحذف pointee في الدمار. للمصفوفات ، تفضل التغليف مثل المتجه و deque. بالنسبة للكائنات الأخرى ، نادراً ما تكون هناك حاجة لتخزينها على الكومة - ما عليك سوى استخدام السكان المحليين وتكوين الكائنات. لا تزال الحاجة إلى مؤشرات السيارات تنشأ مع وظائف تعيد مؤشرات كومة - مثل المصانع والعوائد المتعددة الأشكال.

تقوم المؤشرات المشتركة بحذف pointee عندما يتم تدمير آخر مؤشر مشترك إليه. يكون هذا مفيدًا عندما تريد مخطط تخزين غير عقلاني ومفتوح حيث يمكن أن تختلف مدى الحياة والملكية على نطاق واسع اعتمادًا على الموقف. نظرًا للحاجة إلى الحفاظ على عداد (ذري) ، فهي أبطأ قليلاً من المؤشرات التلقائية. يقول البعض نصف في مزاح أن المؤشرات المشتركة مخصصة للأشخاص الذين لا يستطيعون تصميم أنظمة - تحكم على نفسك.

بالنسبة لنظير أساسي للمؤشرات المشتركة ، ابحث عن مؤشرات ضعيفة أيضًا.

ستنظف المؤشرات الذكية نفسها بعد خروجها من النطاق (وبالتالي إزالة الخوف من معظم تسرب الذاكرة). المؤشرات المشتركة هي مؤشرات ذكية تحافظ على عدد حالات المؤشر الموجودة ، وتنظيف الذاكرة فقط عندما يصل العد إلى الصفر. بشكل عام ، استخدم المؤشرات المشتركة فقط (ولكن تأكد من استخدام النوع الصحيح-هناك شكل مختلف للمصفوفات). لديهم الكثير لتفعله راي.

لتجنب تسرب الذاكرة ، يمكنك استخدام المؤشرات الذكية كلما استطعت. يوجد في الأساس نوعان مختلفان من المؤشرات الذكية في C ++

  • المرجع المرجع (على سبيل المثال التعزيز :: shared_ptr / std :: tr1: shared_ptr)
  • لا يتم حساب المرجع (على سبيل المثال Boost :: scoped_ptr / std :: auto_ptr)

الفرق الرئيسي هو أنه يمكن نسخ المؤشرات الذكية المرجعية المرجعية (واستخدامها في حاويات STD ::) بينما لا يمكن SCOPED_PTR. لا يوجد مؤشرات محسوبة غير مرجعية لا تكاد تكون عامة أو لا تكتم على الإطلاق. المرجع العد دائمًا يقدم نوعًا من النفقات العامة.

(أقترح تجنب auto_ptr ، فإنه يحتوي على بعض العيوب الخطيرة إذا تم استخدامه بشكل غير صحيح)

لإضافة القليل من إجابة سيدوس ، ستوفر المؤشرات الذكية حلاً أكثر استقرارًا من خلال التقاط العديد من الأخطاء. سيكون لدى المؤشرات الخام بعض مزايا Perfromance ويمكن أن تكون أكثر مرونة في بعض الظروف. قد تضطر أيضًا إلى استخدام المؤشرات الأولية عند الارتباط ببعض مكتبات الطرف الثالث.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top