简体   繁体   中英

Use function-pointer as proxy to member-function

Assume a class like this:

class Speaker {
    public:
        void (*saySomething)();
}

The point is that we can instantiate that class and call the stored function pointer in order to make it say something (whatever that turns out to be). The background to such an approach is to have the actual function reside in a shared library and Speaker acts as some sort of wrapper class (The function gets resolved in the library and the pointer is assigned to the variable in the class).

Now consider we have another class that extends Speaker :

class ConstantSpeaker : public Speaker {
    protected:
        std::string message;
        void doSpeak();
}

with the method's implementation like this:

ConstantSpeaker::doSpeak() {
    std::cout << message << std:endl;
}

Now I want to assign the saySomething pointer in a way so that the call is somehow re-routed to ConstantSpeaker::doSpeak() . This however isn't possible directly as doSpeak() is a member function and saySomething is a pointer to a non-member-function.
Another idea I had was to create doSpeak() as a friend-function of ConstantSpeaker instead. Then the pointer-assignment works fine but now doSpeak() would require the object holding the actual message as an argument in order to be able to access the message.

To me it seems as if there should be a (more or less) straight-forward way of doing this given that I can only ever call Speaker::saySomething when having an instance of a Speaker at hand. Therefore the availability of the corresponding object shouldn't be a problem but still I can't figure out how I have to assign that pointer.

The only solution I could come up with is to add a public virtual Speaker::doSaySomething function whose implementation will call the function pointer (which is then no longer public in order to prevent miss-usage) and that can be overwritten by ConstantSpeaker to call ConstantSpeaker::doSpeak() instead.
Is there another solution to this problem?

Another solution is just to use a standard std::function<void()> , and then it can be still declared as public.

Also, instead of bare function pointer, you can use pointer to member function, but be aware about slicing, when using it inside a base class.

But, I think, the most trivial way of doing this is just by using virtual function, like you've mentioned.

Maybe tell more about your context? What is the problem you are going to solve?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM