调用虚拟成员函数的与函数指针基础类定义(Calling base class definition

2019-06-27 06:08发布

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

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 ::绑定创造callFunc一个boost ::函数对象,这是我后来用它来从我的程序的其他部分调用FUNC。 所以,如果升压::绑定或升压::功能有解决这个问题,这也将有助于获得的一些方法。

Answer 1:

当通过引用或指针调用虚方法,你将总是激活发现最派生类型的虚拟调用机制。

最好的办法是添加一个可选的功能,是不是虚拟的。



Answer 2:

什么你试图做的不幸是不可能的。 指针到成员函数被设计为保持所述函数的虚拟性指向的。



Answer 3:

你的问题是,一个成员函数指针是不太一样的裸函数指针。 实际上,它不仅是一个指针,而是一个相当复杂的结构 ,在其细节在编译器实现的程度各不相同。 当您通过语法调用它(this->*fp)()你实际上是在调用它原来的对象,这将导致虚函数调度上。

可能工作的一件事是将其转换为一个非方法指针类型。 这是一个有点摇摇欲坠的,但我认为它应该工作。 你仍然需要通过一个Base * ,但你这样做明确和虚拟函数分派被绕过:

typedef void BasePointer(Base*);

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

更新:好吧,不,你不能这样做的。 这是非法的,并不会是安全的,如果它是合法的。 在C ++ FAQ有更多关于这个 。 但我们知道,没有解决您的问题。 问题是,指针到对象或指针到会员,如果你想打电话给Base::func通过Base指针,它指向的对象必须是一个Base 。 如果能够安排,那么你可以使用一个成员函数指针。

这里还有一个想法,不漂亮,但至少是可行的。 提供的功能Derived ,非虚,即明确要求Base::func 。 指向代替。 它不会扩展,如果你需要做到这一点在很多不同的变种,一般情况下, funccallFunc但它会正常工作的一种方法。



Answer 4:

有没有通过一个函数指针这样做任何具体的原因是什么?

你应该可以这样写:

Base::func();

调用基类的实现。



Answer 5:

除了什么夸克说,一个更普遍的评论是你应该使用的信号/插槽实现,而不是裸函数指针。 升压有一个,有libsigc和一堆别人的。



Answer 6:

这有什么错呢?

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

现在,如果你感到满意的是,它会引发你为什么即使使用函数指针摆在首位的问题。 我认为,一些情况下可能会有帮助。



文章来源: Calling base class definition of virtual member function with function pointer