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

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

سؤال

وأريد أن أدعو تنفيذ الفئة الأساسية من وظيفة افتراضية باستخدام مؤشر دالة عضو.

class Base {
public:
    virtual void func() { cout << "base" << endl; }
};

class Derived: public Base {
public:
    void func() { cout << "derived" << endl; }

    void callFunc()
    {
        void (Base::*fp)() = &Base::func;
        (this->*fp)(); // Derived::func will be called.
                       // In my application I store the pointer for later use,  
                       // so I can't simply do Base::func().
    }
};

في التعليمات البرمجية أعلاه تنفيذ فئة مشتقة من ظائفها سيتم استدعاؤها من callFunc. هل هناك طريقة يمكنني حفظ مؤشر الدالة العضو الذي يشير إلى إسناد :: ظائفها، أو سوف لا بد لي من استخدام using بطريقة ما؟

في طلبي الفعلي يمكنني استخدام دفعة :: ربط لخلق دفعة :: كائن وظيفة في callFunc الذي أنا بعد استخدامها لاستدعاء ظائفها من جزء آخر من برنامجي. حتى إذا دفعة :: ربط أو تعزيز :: وظيفة لديها وسيلة للالتفاف حول هذه المشكلة التي من شأنها أن تساعد أيضا.

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

المحلول

عند استدعاء أسلوب ظاهري عبر إشارة أو مؤشر سوف دائما تفعيل آلية دعوة الظاهرية التي يجد النوع الأكثر مشتقة.

وأفضل رهان هو لإضافة وظيفة بديلة غير افتراضية.

نصائح أخرى

وما نحاول القيام به للأسف غير ممكن. مؤشر إلى وظائف الأعضاء و<م> تصميم للحفاظ على virtualness وظيفة وأشار إلى.

والمشكلة هي أن مؤشر الدالة العضو ليست هي نفس مؤشر دالة العارية. هو في الواقع ليس مجرد مؤشر، ولكن rel="nofollow الهيكل إلى حد كبير أكثر تعقيدا ، التي تختلف في تفاصيلها على مستوى تنفيذ مترجم. عند استدعاء ذلك عن طريق بناء الجملة (this->*fp)() كنت فعلا اصفا إياه على الكائن الأصلي، والذي يسبب وظيفة إرسال الظاهري.

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

typedef void BasePointer(Base*);

void callFunc()
{
    BasePointer fp = (BasePointer *)&Base::func;
    fp(this);
}

<القوي> تحديث: موافق، لا، لا يمكنك أن تفعل ذلك بهذه الطريقة. انها غير قانونية، وأنها لن تكون آمنة إذا كان قانونيا. و C ++ التعليمات ديه <أ href = على "HTTP : //www.parashift.com/c++-faq-lite/pointers-to-members.html#faq-33.4 "يختلط =" نوفولو noreferrer "> المزيد عن هذا . ولكن مع العلم أن لا حل مشكلتك. المسألة هي ان، مؤشر إلى كائن أو مؤشر إلى العضو إذا كنت ترغب في الاتصال Base::func من خلال مؤشر Base، الكائن يتم الإشارة يجب أن <م> أيضا يكون Base. إذا يمكنك ترتيب ذلك، ثم يمكنك استخدام مؤشر دالة عضو.

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

هل هناك أي سبب محدد للقيام بذلك عن طريق مؤشر دالة؟

ويجب أن تكون قادرا على الكتابة فقط:

Base::func();

ولاستدعاء تنفيذ الفئة الأساسية.

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

ما هو الخطأ في هذا؟

(Base(*this).*fp)();

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

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