Calling base class definition of virtual member function with function pointer

≡放荡痞女 提交于 2019-11-28 00:41:46
Martin York

When you call a virtual method via a reference or a pointer you will always activate the virtual call mechanism that finds the most derived type.

Your best bet is to add an alternative function that is not virtual.

What you're trying to do unfortunately isn't possible. Pointer-to-member-functions are designed to maintain the virtualness of the function pointed-to.

Your problem is that a member function pointer is not quite the same as a bare function pointer. It actually isn't just a pointer, but a considerably more complex structure, which varies in its details at the level of the compiler implementation. When you invoke it via the syntax (this->*fp)() you are actually calling it on the original object, which causes virtual function dispatch.

One thing that might work is to cast it to a non-method pointer type. This is a little creaky but I think it should work. You still need to pass a Base * but you do it explicitly and the virtual function dispatch is by-passed:

typedef void BasePointer(Base*);

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

Update: Ok, no, you can't do it that way. It's illegal, and wouldn't be safe it if it was legal. The C++ FAQ has more on this. But knowing that doesn't solve your problem. The issue is that, pointer-to-object or pointer-to-member if you want to call Base::func through a Base pointer, the object it is pointing must also be a Base. If you can arrange that, then you can use a member function pointer.

Here's another thought, not pretty, but at least workable. Provide a function in Derived, non-virtual, that explicitly calls Base::func. Point to that instead. It won't scale if you need to do this in the general case of lots of different variants of func and callFunc but it will work fine for one method.

Is there any specific reason for doing this via a function pointer?

You should be able to just write:

Base::func();

to call the base class implementation.

In addition to what quark says, a more general remark is that you should use a signal/slot implementation rather than a bare function pointer. Boost has one, there's libsigc and a bunch of others.

What's wrong with this?

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

Now if you're satisfied with that, it raises the question of why you're even using a function pointer in the first place. I think some more context might help.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!