簡體   English   中英

使用函數指針調用虛擬成員函數的基類定義

[英]Calling base class definition of virtual member function with function pointer

我想使用成員函數指針調用虛函數的基類實現。

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().
    }
};

在上面的代碼中,func的派生類實現將從callFunc中調用。 有沒有一種方法我可以救一個成員函數指針指向基地:: FUNC,否則我將不得不使用using以某種方式?

在我的實際應用程序中,我使用boost :: bind在callFunc中創建一個boost :: function對象,我后來用它從程序的另一部分調用func。 因此,如果boost :: bind或boost :: function有某種方法來解決這個問題也會有所幫助。

通過引用或指針調用虛方法時,將始終激活查找派生類型最多的虛擬調用機制。

最好的辦法是添加一個非虛擬的替代功能。

不幸的是,你想要做的事情是不可能的。 指針到成員函數被設計為保持所述函數的虛擬性指向的。

您的問題是成員函數指針與裸函數指針不完全相同。 它實際上不僅僅是一個指針,而是一個相當復雜的結構 ,它在編譯器實現的層面上有所不同。 當您通過語法(this->*fp)()調用它時,實際上是在原始對象上調用它,這會導致虛函數調度。

可能有用的一件事是將它轉換為非方法指針類型。 這有點吱吱作響,但我認為它應該有效。 您仍然需要傳遞Base *但是您明確地執行了它並且旁路了虛函數調度:

typedef void BasePointer(Base*);

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

更新:好的,不,你不能這樣做。 這是非法的,如果它是合法的,那就不安全了。 C ++常見問題解答更多內容 但知道這並不能解決你的問題。 問題是,如果要通過Base指針調用Base::func ,指向對象的指針或指向成員的指針,它指向的對象必須是Base 如果你可以安排,那么你可以使用成員函數指針。

這是另一個想法,不是很漂亮,但至少可行。 Derived ,non-virtual中提供一個顯式調用Base::func 指向那個。 如果您需要在funccallFunc的許多不同變體的一般情況下執行此操作,它將無法擴展,但它可以在一個方法中正常工作。

通過函數指針執行此操作是否有任何特定原因?

你應該能夠寫:

Base::func();

調用基類實現。

除了誇克所說的,更一般的說法是你應該使用信號/槽實現而不是裸函數指針。 Boost有一個,有libsigc和其他一些。

這有什么問題?

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

現在,如果你對此感到滿意,那就提出了為什么你甚至在第一時間使用函數指針的問題。 我認為更多的背景可能有所幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM