حذف الوظائف الافتراضية في C ++ 0x
-
29-09-2019 - |
سؤال
ليس من الواضح ما يحدث إذا قمت بحذف طريقة افتراضية في C ++ 0x:
virtual int derive_func() = delete;
هل هذا يعني أن هذه الفئة وكل ما يرث منه لا يمكنه تحديد/تنفيذ derive_func()
طريقة؟ أم أن هذا خطأ غير قانوني/تجميع؟
المحلول
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2326.html#delete
A deleted virtual function may not override a non-deleted virtual function and vice-versa.
بمعنى أنه غير مجدي إلى حد ما (كما قرأته على الأقل) سيكون الاستخدام الصحيح الوحيد هو:
struct A{
virtual void b() = delete;
};
struct B:A{
virtual void b() = delete;
};
وهو أمر غير مجدي تمامًا ، حيث لا يمكن استدعاء الوظيفة أبدًا. بالنسبة للوظائف غير الافتراضية ، يكون الاستخدام أكثر مبررًا
تحرير لتكون واضحًا تمامًا ، هذه هي العلاقة الوحيدة الممكنة ، قد لا ينفذ الأطفال ولا يجوز لك حذف ظاهري غير محذوف.
نصائح أخرى
لقد حصلت عليه بشكل صحيح, ، لكنني أريد أن أشير إلى أنه في مسودة C ++ 11 النهائية (N3337) ، انتقلت اللغة المقابلة إلى القسم 10.3#16:
يجب ألا تتجاوز الدالة ذات التعريف المحذوف وظيفة لا تحتوي على تعريف محذوف. وبالمثل ، لا يجوز لدالة لا تحتوي على تعريف محذوف تجاوز وظيفة مع تعريف محذوف.2
يبدو واضحا إلى حد ما إلي (القسم 8.4.3#1) أن أ التعريف المحذوف في الواقع يعتبر ك تعريف, ، وفي الواقع تعريف مضمّن ، مما يعني أن التعريف المحذوف يفي 10.3#11:
يجب تعريف الوظيفة الافتراضية المعلنة في الفصل ، أو إعلانها نقيًا في تلك الفئة ، أو كليهما ؛ ولكن لا يلزم التشخيص.2
ومع ذلك ، يبدو أن التطبيقات الحالية لا توافق. ها هي حالة الاختبار الخاصة بي:
struct Base {
virtual void bar();
virtual void foo() = delete;
};
void Base::bar() { } // a definition of the first non-inline virtual function
int main() { Base b; }
ينتج Clang برنامجًا غير قابل للارتباك:
Base::foo
مذكور في VTABLEBase
. وإذا قمت بتبديل ترتيبfoo
وbar
, ، يشكو الرابط من أن VTABLE بأكمله مفقود (لأن كلانج يعتقدfoo
هي وظيفة غير خط مع عدم وجود تعريف). لقد قدمت هذا كخشب; ؛ سنرى ما يفكر فيه المطورون.يشتكي GCC من "استخدام"
foo
في نهاية وحدة الترجمة ، عندما يخلق VTABLE ؛ لكنه يحدد بشكل صحيحbar
كأول وظيفة عضو افتراضي غير خط ، بغض النظر عن ترتيبfoo
وbar
.