سؤال

الجميع،

لقد نشرت هذا مؤخرا سؤال على تصميم DAL.من ذلك يبدو أن تمرير مرجع إلى كائن إلى دالة، مع قيام الدالة بعد ذلك بملء هذا الكائن، سيكون واجهة جيدة لطبقة الوصول إلى البيانات C++، على سبيل المثال.

  bool DAL::loadCar(int id, Car& car) {} 

أتساءل الآن عما إذا كان استخدام إشارة إلى Boost::shared_ptr سيكون أفضل، على سبيل المثال.

  bool DAL::loadCar(int id, boost::shared_ptr<Car> &car)

أي أفكار؟هل يقدم أحدهما مزايا على الآخر؟

ما هي الآثار المترتبة على تطبيق صواب const على كلا النداءين؟

شكرا لك مقدما.

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

المحلول

مثل الهيئة الفرعية للتنفيذ يقول: "يعتمد الأمر على ما تفعله الوظيفة."

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

  • لا يزال من الممكن استخدام الوظيفة من قبل العملاء الذين لا يستخدمون Share_ptr، وتستخدم لكائنات المكدس، وما إلى ذلك.
  • لا يزال استخدام الوظيفة مع Shared_ptr تافهًا - Shared_ptr لديه عامل إلغاء مرجعي يقوم بإرجاع مرجع
  • تمرير NULL غير ممكن
  • كتابة أقل
  • لا أحب استخدام "الأشياء" عندما لا أحتاج إلى ذلك

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

نصائح أخرى

وذلك يعتمد على ما تفعله وظيفة.

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

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

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

وأنا لا أفهم تماما لماذا كنت أعتقد أن الإشارة إلى مؤشر الذكية ستكون "أفضل" - لا وظيفة المتصل استخدام مؤشر الذكية بالفعل

وأما عن الآثار المترتبة على "CONST" ... هل يعني شيء من هذا القبيل

bool DAL::loadCar(int id, const Car& car) {}

و؟ إذا كانت الإجابة بنعم، فإنه سيكون له نتائج عكسية، يمكنك التواصل مع المترجم حقيقة أن "سيارة" لا يتغير (ولكن يفترض تريد أن التغيير!).

وأو هل يعني لجعل وظيفة "CONST"، شيء من هذا القبيل

class DAL{
   bool loadCar(int id, Car& car) const;
}

في هذه الحالة، يمكنك كومونيكاتي للمستخدم مترجم / API أن طريقة "loadCar" لا تعديل الكائن DAL. انها فكرة جيدة للقيام بذلك إذا كان هذا صحيحا - وليس فقط أنه تمكن بعض التحسينات مترجم، لكنه عموما هو شيء جيد لتحديد في "العقد" (وظيفة توقيع) أن وظيفة يجعل أي تعديلات على DAL، وخاصة إذا إجراء هذا الافتراض الضمني في التعليمات البرمجية (بهذه الطريقة يمكنك التأكد من أن هذا يبقى صحيحا، وأنه في المستقبل سوف لا أحد تعديل وظيفة "loadCar" بطريقة من شأنها أن تغير "DAL" وجوه)

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

وأنا عادة العمل مع المؤشرات التقليدية، وليس زيادة (بدون مشكلة، بالمناسبة) لذلك أنا حقا لا يمكن التعليق على البديل الأخير.

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