سؤال

في بعض الأحيان أحتاج إلى فضح بعض أعضاء الفصل. على سبيل المثال في المثال التالي class Mechanic قد تحتاج إلى وصول مباشر إلى Engine مكون. لقد قرأت عدة مرات أنه يجب الوصول إلى جميع الحقول بواسطة أساليب Mutator (ملحق) بسبب عدة أسباب. ولكن هل هناك أي ميزة عند توفير Getter المرجعية غير المؤسسة:

class Car
{
    public:
        Engine & engine()
        {
           return m_engine;
        }

        //as a consequence you will also need to provide const version
        const Engine & engine() const
        {
           return m_engine;
        }

    private:
       Engine m_engine;
}

أكثر من مجرد جعل مكون محرك عام:

class Car
{
    public:
        Engine engine;
}

يمكنك أيضا استبدال public مع protected إذا كنت لا تحب هذا المثال. في الحياة الواقعية ، لديك شيء Simillar في Java عندما يتعلق الأمر System.in أو System.out. يبدو أن تكون متوافقًا تمامًا مع ما يقوله بعض الناس ، ستحتاج إلى إجراء مكالمات مثل System.getInstance().getOut().println("hello world"). لا أرى أي فائدة باستثناء الكثير من الكود البيروقراطي في مثل هذه الحالات.

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

المحلول 5

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

نصائح أخرى

يمكن أن تكون مفيدة عندما تكون القيمة التي تعود إليها في الواقع على الكومة.

template<class T> class Singleton
{
private:
    static T* m_pSingleton;

public:
    T& getSingleton() { assert(m_pSingleton); return(*m_pSingleton); };

}; // eo class Singleton

getters الصريح والمستقبين يستطيع تكون مفرطة في الأوكسرة. ذلك يعتمد على الوضع الخاص بك.

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

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

ومع ذلك ، للإجابة على سؤالك ، أ غير const ربما لا يكون جادتر منطقيًا. يجب أن يكون النموذج الأولي الخاص بك Engine & engine() const; ؛ وإلا فلن تتمكن من الاتصال به const Car أشياء.

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

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

بالنسبة لي من المنطقي هنا:

image(i,j) = 234;

بدلاً من التفكير في تعريض الأعضاء الخاصين في الفصل ، فكر أكثر على غرار أساليب الاتصال على تلك الفصول. قرأت مقالة جافا مثيرة للاهتمام ، لماذا أساليب Getter و Setter شريرة, ، وهو ما ينطبق على C ++ بقدر ما ينطبق على Java.

نعم ، من المنطقي - من أجل الصيانة والتحقق من الصحة والاتساق.

قد تحتاج إلى تغيير العديد من جوانب الفصل في المستقبل ، فإن توفير ملحق يمكن أن يساعد في تقليل كسر رمز العميل.

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

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

في هذه الحالة ، تفضل أن تحتاج إلى Car.fix(const Mechanic&) الوظيفة التي تعطي المحرك بعد ذلك Mechanic, ، قل: Engine.fix(const Mechanic&), ، كما أفترض حالة Engine سيتم تعديلها.

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

تريد فقط فضح بيانات جديدة تنبعث منها الفئة. يقول Car.get_exhaust() و ال Car ليس لديه العادم ، فقط ينتجه ، عندما تسأل ذلك. ؛)

أو Fire Riefle.fire() في حين لا يمكن الوصول إلى Riefle::Trigger سيتم إصلاحه بواسطة الميكانيكي مثل: Trigger.fix_by(Mechanic) ثم fix_by سوف ندعو يقول Mechanic.add_working_hour(0.5). وجه ضاحك

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