يجب أن أفضل المؤشرات أو المراجع في بيانات الأعضاء؟

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

  •  23-08-2019
  •  | 
  •  

سؤال

هذا مثال مبسط لتوضيح السؤال:

class A {};

class B
{
    B(A& a) : a(a) {}
    A& a;
};

class C
{
    C() : b(a) {} 
    A a;
    B b; 
};

لذلك B مسؤولة عن تحديث جزء من C. ركض الرمز من خلال الوبر والذي نظريه بشأن العضو المرجعي: لينت # 1725.وبعد هذه المحادثات حول العناية بالنسخ والواجبات الافتراضية التي هي عادلة بما فيه الكفاية، ولكن النسخ والتخصص الافتراضي هي أيضا سيئة أيضا مع المؤشرات، لذلك هناك ميزة ضئيلة هناك.

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

أود عموما استخدام مؤشر فقط في بيانات الأعضاء عندما يكون المؤشر فارغا أو قد يتغير. هل هناك أي أسباب أخرى تفضل المؤشرات على المراجع لأعضاء البيانات؟

هل صحيح أن القول إن كائن يحتوي على مرجع يجب أن يكون قابلا للتأريض، نظرا لأنه يجب عدم تغيير المرجع مرة واحدة؟

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

المحلول

تجنب الأعضاء المرجعين، لأنهم يقيدون ما يمكن أن يفعله تنفيذ الفصل (بما في ذلك، كما ذكر، منع تنفيذ مشغل الواجب) ولا تقدم أي فوائد لما يمكن أن يوفره الفصل.

مشاكل المثال:

  • أنت مجبرت على تهيئة المرجع في قائمة "سندات" كل منشئ ": لا توجد وسيلة للعاملين هذا التهوية في وظيفة أخرى (حتى C ++ 0x، على أي حال تعديل: C ++ الآن تفويض المانحين)
  • لا يمكن انتعاش المرجع أو تكون فارغة. يمكن أن يكون هذا ميزة، ولكن إذا كان الرمز يحتاج إلى تغيير للسماح للاحتداد أو للعضو أن يكون فارغا، فإن جميع استخدامات الأعضاء الحاجة إلى التغيير
  • على عكس أعضاء المؤشر، لا يمكن استبدال المراجع بسهولة استبدالها بمؤشرات ذكية أو مزايكين أثناء إعادة الإنفاق
  • كلما تم استخدام مرجع يبدو مثل نوع القيمة (. المشغل إلخ)، ولكن يتصرف مثل مؤشر (يمكن استرخى) - لذلك على سبيل المثال دليل أسلوب جوجل لا يشجع ذلك

نصائح أخرى

حكمي الإبهامي:

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

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

لذلك بالنسبة للأجسام التجارية، من الجيد جدا وصف علاقات فردية وواحدة إلى أخرى كمراجع وليس مؤشرات.

وربما لا بأس أن تصف علاقة واحدة أو صفر كمؤشر.

لذلك لا "لا يمكننا تعيين" ثم عامل.
الكثير من المبرمجين تعتاد فقط مع المؤشرات وهذا هو السبب في أنهم سيجدون أي حجة لتجنب استخدام المرجع.

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

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

في مثل هذه الحالات، تأكد من إجراء مشغل الواجب (وغالبا ما يكون أيضا منشئ النسخ) غير قابل للاستخدام (عن طريق الوراثة من boost::noncopyable أو إعلانهم خاصين).

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

كما يبدو أن الجميع يقومون بتسليم القواعد العامة، سأقدم اثنين:

  • أبدا، استخدم مراجع الاستخدام أبدا كأعضاء فئة. لم أفعل ذلك أبدا في الكود الخاص بي (باستثناء إثبات لنفسي أنني كنت على حق في هذه القاعدة) ولا يمكن أن تخيل القضية التي سأفعل فيها ذلك. تكون الدلالات مربكة للغاية، وهي في الحقيقة ليست المراجع التي تم تصميمها ل.

  • دائما، دائما، استخدم المراجع عند تمرير المعلمات إلى الوظائف، باستثناء الأنواع الأساسية، أو عندما تتطلب الخوارزمية نسخة.

هذه القواعد بسيطة، وقد وقفتني في حالة جيدة. أترك قواعد في استخدام المؤشرات الذكية (ولكن من فضلك، وليس auto_ptr) كأعضاء فئة للآخرين.

نعم لل: هل صحيح أن القول إن كائن يحتوي على مرجع يجب أن يكون قابلا للتأريض، نظرا لأنه يجب عدم تغيير المرجع مرة واحدة؟

قواعد الإبهام لأعضاء البيانات:

  • لا تستخدم مرجعا أبدا، لأنه يمنع التعيين
  • إذا كانت صفك مسؤولا عن حذف، فاستخدم Scoped_ped_ptr (ما هو أكثر أمانا من Auto_Ptr)
  • خلاف ذلك، استخدم مؤشر أو مؤشر const

أود عموما استخدام مؤشر فقط في بيانات الأعضاء عندما يكون المؤشر فارغا أو قد يتغير. هل هناك أي أسباب أخرى تفضل المؤشرات على المراجع لأعضاء البيانات؟

نعم. قراءة رمزك. يجعل المؤشر أكثر وضوحا أن العضو هو مرجع (من المفارقات :))، وليس كائنا مضبوطا، لأنه عند استخدامه، يجب عليك إلغاء الإشارة إليه. وأنا أعلم أن بعض الناس يعتقدون أنهم من الطراز القديم، لكن ما زلت أعتقد أنه ببساطة يمنع الارتباك والأخطاء.

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

إذا فهمت السؤال بشكل صحيح ...

المرجع كمعلمة وظيفة بدلا من المؤشر:كما أشرت، لا يوضح المؤشر من يمتلك تنظيف / تهيئة المؤشر. تفضل نقطة مشتركة عندما تريد مؤشرا، إنه جزء من C ++ 11، وضعف_PTR عندما تكون صحة البيانات غير مضمونة من خلال مدى عمر قبول البيانات المدببة إلى البيانات؛ أيضا جزء من C ++ 11. باستخدام مرجع كمعلمة دالة تضمن أن المرجع غير فارغ. يجب عليك تخريب ميزات اللغة للحصول على هذا، ونحن لا نهتم برموز المدفع فضفاضة.

مرجع عضو عضو AA:على النحو الوارد أعلاه فيما يتعلق بصحة البيانات. هذا يضمن البيانات المدببة للبيانات، ثم المشار إليها، صالحة.

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

في مثالك، وهو أمر مربكي بعض الشيء (سأحاول حقا العثور على تطبيق أكثر وضوحا)، وهو ما يستخدمه B مضمونة لمدى عمر B، لأن B هو عضو في أ، لذلك مرجع يعزز هذا و (ربما) أكثر وضوحا.

وفي حالة فقط (وهو غطاء منخفض محتمل لأنه لن يكون منطقيا في سياق الرموز الخاصة بك)، بديل آخر، لاستخدام المعلمة غير المرجعية غير المرجعية، وسيقوم بنسخها، وجعل النموذج عديم الفائدة - أنا حقا لا تعتقد أنك تعني هذا كبديل.

أيضا، هذا يضمن أيضا أنك غير قادر على تغيير البيانات المشار إليها، حيث يمكن تعديل المؤشر. سيعمل مؤشر CONS، فقط إذا لم يكن الأمر المشار إليه / المؤشر إلى البيانات غير قابل للتغيير.

المؤشرات مفيدة إذا لم يتم ضمان المعلمة ل B، أو يمكن إعادة تعيينها. وأحيانا يكون المؤشر الضعيف هو مجرد مطول للغاية بالنسبة للتنفيذ، وعدد جيد من الأشخاص إما لا يعرفون ما هو ضعيف_PTR، أو لا يكرهونها.

المسيل للدموع هذه الإجابة، من فضلك :)

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