متى يجب أن أستخدم المتغيرات المؤقتة؟ [مغلق

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

  •  02-10-2019
  •  | 
  •  

سؤال

على وجه التحديد ، أتساءل أي من هذه يجب أن أكتب:

{
    shared_ptr<GuiContextMenu> subMenu = items[j].subMenu.lock();
    if (subMenu)
        subMenu->setVisible(false);
}

أو:

{
    if (items[j].subMenu.lock())
        items[j].subMenu.lock()->setVisible(false);
}

لست مطالباً باتباع أي إرشادات نمط. بعد التحسين ، لا أعتقد أن أي من الخيارات تحدث فرقًا في الأداء. ما هو بشكل عام النمط المفضل ولماذا؟

تحرير: نوع العناصر [j] .Submenu هو Boost :: Pream_ptr. Lock () ينشئ مشاركة _ptr منه. هناك بالفعل اختلاف غامض في الإصدارين أعلاه ، فيما يتعلق بالوقت الذي يستمر فيه المشترك المؤقت ، لذلك قمت بلف مثالي في {braces} لحل الغموض هناك.

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

المحلول

طريقة بديلة:

if(shared_ptr<GuiContextMenu> subMenu = items[j].subMenu.lock()) {
    subMenu->setVisible(false);
}
//subMenu is no longer in scope

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

نصائح أخرى

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

بخلاف ذلك:

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

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

أعتقد أنك على صواب بشأن أي اختياري لا يختلف بعد التحسين.

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

يحرر:

اشترى Mmyers تعليق جيد. نعم ، كن حذرًا بشأن الاتصال lock() مرتين ، على عكس مرة واحدة فقط. سيكون لديهم تأثيرات مختلفة اعتمادا على تنفيذك.

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

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

if( fn() > 0 ) ...

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

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

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

if( isValid && fn() ) ...

لن تسمى الوظيفة أبدًا Isvalid خاطئة.

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

في هذا المثال المحدد ، أعتقد أن ذلك يعتمد على ماذا lock() يفعل. هل الوظيفة باهظة الثمن؟ هل يمكن أن تُرجع أشياء مختلفة في كل مرة تسمى الوظيفة (هل يمكن أن تُرجع مؤشرًا في المرة الأولى والخلفية في المرة الثانية)؟ هل هناك خيط آخر يمكن تشغيله بين المكالمتين lock()?

لهذا المثال ، تحتاج إلى فهم سلوك lock() وبقية الكود الخاص بك لاتخاذ قرار ذكي.

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

أيضًا ، كما أشار Mmyers ، يعتمد ذلك أيضًا على ما يفعله Lock (). بشكل عام ، إذا كانت طريقة getter بسيطة أو شيء من هذا القبيل ، فستكون بخير.

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

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

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

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