我想使用成员函数指针调用虚函数的基类实现。

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中调用。有没有办法可以保存指向Base :: func的成员函数指针,还是我必须以某种方式使用

在我的实际应用程序中,我使用boost :: bind在callFunc中创建一个boost :: function对象,我后来用它从程序的另一部分调用func。因此,如果boost :: bind或boost :: function有某种方法来解决这个问题也会有所帮助。

有帮助吗?

解决方案

当您通过引用或指针调用虚方法时,您将始终激活查找派生类型最多的虚拟调用机制。

最好的办法是添加一个非虚拟的替代功能。

其他提示

不幸的是,你想要做的事情是不可能的。指向成员函数的指针设计以维护指向的函数的虚拟性。

您的问题是成员函数指针与裸函数指针不完全相同。它实际上不仅仅是一个指针,而是一个相当复杂的结构,它在编译器实现的级别上有所不同。当您通过语法(this-&gt; * fp)()调用它时,实际上是在原始对象上调用它,这会导致虚函数调度。

可能有用的一件事是将它转换为非方法指针类型。这有点吱吱作响,但我认为它应该有效。您仍然需要传递 Base * ,但是您明确地执行了此操作并且旁路了虚拟函数调度:

typedef void BasePointer(Base*);

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

更新:好的,不,你不能这样做。这是非法的,如果它是合法的,那就不安全了。 C ++常见问题解答更多内容。但知道这并不能解决你的问题。问题是,如果要通过 Base 指针调用 Base :: func ,指向对象的指针或指向成员的指针,它所指向的对象必须 Base 。如果你可以安排,那么你可以使用成员函数指针。

这是另一个想法,不漂亮,但至少可行。在 Derived 中提供一个非虚拟的函数,它显式调用 Base :: func 。指向那个。如果您需要在 func callFunc 的许多不同变体的一般情况下执行此操作,它将无法扩展,但它将适用于一个方法。

通过函数指针执行此操作是否有任何特定原因?

你应该可以写:

Base::func();

调用基类实现。

除了夸克所说的,更一般的说法是你应该使用信号/槽实现而不是裸函数指针。 Boost有一个,有libsigc和其他一些。

这有什么问题?

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

现在,如果你对此感到满意,它就会提出一个问题,即为什么你甚至在第一时间使用函数指针。我认为更多的背景可能有所帮助。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top