وظائف افتراضية غير نقية مع المعلمات ممارسة سيئة؟

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

  •  06-07-2019
  •  | 
  •  

سؤال

ولدي فئة أساسية مع وظيفة افتراضية اختياري

class Base {
    virtual void OnlyImplementThisSometimes(int x) {}
};

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

class Base {
    virtual void OnlyImplementThisSometimes(int x) 
    {
        x = 0;
    }
};

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

class Derived : public Base {
    void OnlyImplementThisSometimes(int x, int y) { // some code }
};

Derived d;
Base *b = dynamic_cast<Base *>(&d);
b->OnlyImplementThisSometimes(x); // calls the method in the base class

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

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

المحلول

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

virtual void OnlyImplementThisSometimes(int ) { }

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

نصائح أخرى

ونحن تعريف _unused الماكرو ك:

#define _unused(x) ((void)x)

وبعد ذلك تحديد وظيفة على النحو التالي:

virtual void OnlyImplementThisSometimes(int x) { _unused( x );}

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

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

وأو تطبيق الافتراضي يمكن رمي استثناء

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

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

int func(int x)
{
   (void) x;
}

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

وI تنفيذ ظيفتين فارغة الظاهري في الفئة الأساسية: التهيئة () وتنظيف (). فئة مشتقة احدة مترابطة لا impliment لهم، ولكن واحدة موليت الخيوط لا.

ولدي وظيفة مصنع خلق approprite فئة مشتقة ثم إرجاع المؤشر. رمز العميل وحده يعلم عن نوع الفئة الأساسية وتدعو التهيئة () وتنظيف (). كلا السيناريوهين تفعل الشيء الصحيح.

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

وانها ليست ممارسة سيئة وانها لغة مشتركة لتحديد أجزاء من فئة اختيارية لتنفيذها.

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

class mouse_listener{
public:
    virtual ~mouse_listener() {}

    virtual void button_down(mouse_button a_Button) {}
    virtual void button_up(mouse_button a_Button) {}
    virtual void scroll_wheel(mouse_scroll a_Scroll) {}
    virtual void mouse_move_abs(math::point a_Position) {}
    virtual void mouse_move_rel(math::point a_Position) {}
};

وراجع للشغل، إذا كنت تعرف الفئة الأساسية، فإن هناك أبدا أي حاجة للقيام ديناميكية <م> حتى -casts، أي من المشتقة إلى القاعدة.

Base *b = &d;

وسوف نفعل فقط كذلك، يجب بدلا من ذلك تستخدم dynamic_cast<> عند أسفل الصب، أي من القاعدة إلى المستمدة:

if((Derived *d = dynamic_cast<Derived *>(b)) != 0)
{
  // use d
}

(وبالطبع في حالة أسفل الزهر، static_cast<> سوف تعمل عادة كذلك.)

وجرب هذا:

class Base {
    virtual void OnlyImplementThisSometimes(int x) = 0;
};

ولقد كان منذ بعض الوقت لقد فعلت أشياء من هذا القبيل ولكن أعتقد أن هذه هي الطريقة التي تقوم بتعريف دالة ظاهري.

وأيضا كما قال آخرون، أسماء المتغيرات اختيارية في الإعلانات وظيفة من هذا القبيل.

ويظهر أبسط الإجابة على هذا أدناه:

class Base {
    virtual void OnlyImplementThisSometimes(int x) { x;}
};

وإشارة بسيطة إلى المتغير الذي لا شيء على الاطلاق سيزيل كل التحذيرات (من VC ++ عند أعلى مستوى على أي حال).

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