هل هناك طريقة لمنع تجاوز الطريقة في الفئات الفرعية؟

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

  •  09-06-2019
  •  | 
  •  

سؤال

هل يعرف أي شخص وجود ميزة أو تقنية لغة في C++ لمنع الفصل الفرعي من تجاوز طريقة معينة في الفصل الأصلي؟

class Base {
public:
    bool someGuaranteedResult() { return true; }
};

class Child : public Base {
public:
    bool someGuaranteedResult() { return false; /* Haha I broke things! */ }
};

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

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

المحلول

بضعة أفكار:

  1. اجعل وظيفتك خاصة.
  2. لا تجعل وظيفتك افتراضية.هذا لا يمنع في الواقع من تظليل الوظيفة بتعريف آخر.

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

حظ سعيد!

نصائح أخرى

عندما يمكنك استخدام final محددًا للطرق الافتراضية (المقدمة مع C++ 11)، يمكنك القيام بذلك.اسمحوا لي أن أقتبس موقع الوثيقة المفضل لدي:

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

تتكيف مع المثال الخاص بك الذي سيكون مثل:

class Base {
public:
    virtual bool someGuaranteedResult() final { return true; }
};

class Child : public Base {
public:
    bool someGuaranteedResult() { return false; /* Haha I broke things! */ }
};

عندما يتم تجميعها:

$ g++ test.cc -std=c++11
test.cc:8:10: error: virtual function ‘virtual bool Child::someGuaranteedResult()’
test.cc:3:18: error: overriding final function ‘virtual bool Base::someGuaranteedResult()’

عندما تعمل مع برنامج التحويل البرمجي لـ Microsoft، قم أيضًا بإلقاء نظرة على ملف sealed الكلمة الرئيسية.

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

مثل آحرون هنا يكون مقترح, ، أنت حقا لا تستطيع منع هذا.ويبدو أن هذا أيضًا هو بالأحرى أسئلة شائعة.

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

لا أعتقد أن هناك طريقة للقيام بذلك. وأود أيضًا أن أعرف سبب قرارك بمنع الفئات المشتقة من تجاوز وظائف الفئة الأساسية.

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

وهنا مثاله مرة أخرى

تحدد الفئة الأصل وظيفة:

int foo() { return 1; }

فئة الطفل، وراثة الوالد تحدد نفس الوظيفة مرة أخرى (وليس التجاوز):

int foo() { return 2; }

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

هذا هو ما يسأل.

تحذير وقت الترجمة حول إخفاء الوظيفة الموروثة غير الافتراضية X.

قم بتغيير إعدادات المترجم الخاص بك لجعله خطأ بدلاً من التحذير.

أعتقد أن ما يحذرك منه المترجم هو ما يخفيه !!هل يتم تجاوزه فعلا؟

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

هذا مثير للاهتمام.حاول إنشاء برنامج اختبار صغير مستقل للمترجم الخاص بك.

كنت أبحث عن نفس الشيء وتوصلت بالأمس إلى هذا السؤال [القديم إلى حد ما].

لقد وجدت اليوم كلمة أساسية أنيقة لـ c++ 11: final .اعتقدت أنه قد يكون مفيدا للقراء المقبلين.

http://en.cppreference.com/w/cpp/language/final

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

أي:

Parent* obj = new Child();

ما لم تجعل الطريقة افتراضية، فلن تتمكن الفئة الفرعية من تجاوزها.إذا كنت تريد منع فصول الأطفال من الاتصال بها، فاجعلها خاصة.

لذا بشكل افتراضي، يفعل C++ ما تريد.

لا تختلف محاولة منع شخص ما من استخدام نفس اسم وظيفتك في فئة فرعية كثيرًا عن محاولة منع شخص ما من استخدام نفس اسم الوظيفة العامة كما أعلنت في مكتبة مرتبطة.

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

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

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

تعتبر أساليب C++ خاصة ولا يمكن تجاوزها افتراضيًا.

  • لا يمكنك تجاوز طريقة خاصة
  • لا يمكنك تجاوز غيرvirtual طريقة

هل ربما تقصد الحمولة الزائدة؟

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