هل استخدام الكثير من الأشياء الثابتة سيئ أم جيد؟

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

  •  09-06-2019
  •  | 
  •  

سؤال

أحب استخدام الوظائف الثابتة في لغة C++ كوسيلة لتصنيفها، كما تفعل لغة C#.

Console::WriteLine("hello")

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

ماذا عن static const?

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

المحلول

ولكن هل هو جيد أم سيء

الصفة الأولى التي تتبادر إلى الذهن هي "غير ضرورية".تحتوي لغة C++ على وظائف ومساحات أسماء مجانية، فلماذا تحتاج إلى جعلها وظائف ثابتة في الفصل الدراسي؟

استخدام الأساليب الثابتة في الفئات غير القابلة للتثبيت في C# وJava هو الحل البديل لأن هذه اللغات لا تحتوي على وظائف مجانية (أي الوظائف الموجودة مباشرة في مساحة الاسم، وليس كجزء من فئة).C++ لا يوجد به هذا العيب.مجرد استخدام مساحة الاسم.

نصائح أخرى

أنا أؤيد استخدام الثبات المهام.هذه الأمور منطقية خاصة عند تنظيمها في وحدات (static class شركة#).

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

شيء صغير:الوظائف الثابتة جيدة، والبيانات الثابتة سيئة.

أولئك الذين يقولون أنه يمكن استبدال الوظائف الثابتة بمساحات الأسماء مخطئون، إليك مثال بسيط:

class X
{
   public:
   static void f1 ()
   {
      ...
      f2 ();
   }

   private:
     static void f2 () {}
};

كما ترون، وظيفة ثابتة العامة f1 يستدعي وظيفة ثابتة أخرى، ولكن خاصة f2.

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

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

استخدم مساحات الأسماء لإنشاء مجموعة من الوظائف:

namespace Console {
    void WriteLine(...) // ...
}

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

أحد الأسباب المحددة لكون البيانات الثابتة سيئة، هو أن C++ لا تقدم أي ضمانات بشأن ترتيب تهيئة الكائنات الثابتة في وحدات الترجمة المختلفة.من الناحية العملية، يمكن أن يسبب هذا مشاكل عندما يعتمد كائن ما على كائن آخر في وحدة ترجمة مختلفة.يناقش سكوت مايرز هذا الأمر في البند 26 من كتابه أكثر فعالية C++.

أتفق مع فرانك هنا، ليست هناك مشكلة في الوظائف الثابتة (العالمية) (بالطبع بشرط أن تكون منظمة)..تبدأ المشاكل في التسلل حقًا فقط عندما يفكر الناس "أوه، سأجعل نطاق هذه البيانات أوسع قليلاً".المنحدر الزلق :)

لوضع الأمر في نصابه الصحيح.. البرمجة الوظيفية ;)

مشكلة الوظائف الثابتة هي أنها يمكن أن تؤدي إلى تصميم يكسر التغليف.على سبيل المثال، إذا وجدت نفسك تكتب شيئًا مثل:

public class TotalManager
{
    public double getTotal(Hamburger burger)
    {
        return burger.getPrice() + burget.getTax();
    }
}

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

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

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

للتنظيم، استخدم مساحات الأسماء كما ذكرنا سابقًا.

بالنسبة للبيانات العالمية، أحب استخدام ملف مفردة Pattern لأنه يساعد في حل مشكلة ترتيب التهيئة غير المعروف للكائنات الثابتة.بمعنى آخر، إذا كنت تستخدم الكائن ككائن مفرد، فمن المؤكد أنه سيتم تهيئته عند استخدامه.

تأكد أيضًا من أن وظائفك الثابتة عديمة الحالة بحيث تكون آمنة.

عادةً ما أستخدم الإحصائيات فقط مع نظام الأصدقاء.

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

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

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

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