how to pass method of child as parameter to function in parent - c++

In the following exceedingly abbreviated classes I would like to define in the base a method (ProcessLines) that would iterate over a set of database records, passing each record as a parameter to a function that is only defined in the child class. Obviously the Base is a virtual class that will never be instantiated on its own.
Class Base {
public:
typedef ProcLineFunc( Long *Line );
void ProcessLines( ProcLineFunc pf);
}
Class Child{
void DoWork( Long *Line) { //do something}
}
I'm not sure how to implement this. If I redeclare ProcessLines in the child and just call the parent method, I get the same error message as if I call ProcessLines in the code that creates the child.
Child c(//something);
c.ProcessLines(c.DoWork);
Gives me a compiler message:
[BCC32 Error] main.cpp(67): E2034 Cannot convert 'bool (* (_closure )(long *))(long )' >to 'int ()(long *)'
Full parser context
main.cpp(56): class Add2Chan
main.cpp(78): decision to instantiate: bool Add2Chan::ProcessByLines()
--- Resetting parser context for instantiation...
main.cpp(67): parsing: bool Add2Chan::ProcessByLines()
I'm fairly new to c++ and the E2034 error message scares the daylights out of me.
Please help. I used a typedef so that I can, in my child classes call ProcessLines multiple times, passing in different functions as I go.

Normally you would do this sort of thing with a protected, pure virtual function:
class Base {
public:
ProcessLines() {
//Logic to process lines here, obviously psuedo-code
while(moreLines) {
ProcessLine(line);
}
}
protected:
virtual void ProcessLine(const Line& line) = 0;
}
class Child : public Base {
protected:
void ProcessLine(const Line& line) { //Logic to process the line for this type }
};
class DifferentChild : public Base {
protected:
void ProcessLine(const Line& line) { //Logic to process the line for DifferentChild }
};
I think this is the kind of thing you're looking for. It appears to me like you're trying to implement polymorphism in an odd way, but this is the normal way to do it in C++.

Instead of using pointers to functions, use pointers to objects. Accept the limitation that your function is going to be called DoWork and nothing else, and there can only be one such function in each class. This is not a bad limitation. Declare the (pure virtual) function in a class (which is called an interface), and derive classes from it (they are said to implement an interface).
struct DoingWork
{
virtual void DoWork(long *Line) = 0; // does some work on a list
};
struct DoingGreatWork: DoingWork
{
virtual void DoWork(long *Line) {printf("Great work\n");}
};
struct DoingSlightWork: DoingWork
{
virtual void DoWork(long *Line) {printf("Slight work\n");}
};
Using this example:
class Base {
public:
void ProcessLines(DoingWork& object) {
//Logic to process lines here
while(moreLines) {
object.DoWork(line);
}
}
};
class Whatever // no need to derive from Base
{
void DoStuff()
{
Base object;
object.ProcessLines(DoingGreatWork());
object.ProcessLines(DoingSlightWork());
}
}
If the working objects have to have access to the calling object, initialize them like this:
class Whatever // no need to derive from Base
{
struct DoingElaborateWork: DoingWork
{
Whatever& caller;
DoingElaborateWork(Whatever& caller): caller(caller) {}
virtual void DoWork(long *Line)
{
printf("Doing work requested by %s\n", caller.name());
}
};
void DoStuff()
{
Base object;
object.ProcessLines(DoingElaborateWork(*this));
}
const char* name() {return "Whatever";}
}
P.S. They say that "in C++03 functions are second-class citizens" because you cannot do with functions what you can do with objects (like this solution i provide). I heard that in C++11 functions are much improved, but i am not sure about the details.

Since you are doing this in C++Builder, you can utilize its __closure extension to do exactly what you asked for (some portions of the VCL do exactly this for their own callbacks):
class Base
{
public:
virtual ~Base() {}
typedef void (__closure *ProcLineFunc)( Long *Line );
void ProcessLines( ProcLineFunc pf);
};
class Child : public Base
{
public:
void DoWork( Long *Line) { //do something}
};
Child c(...);
c.ProcessLines(c.DoWork);

Related

C++ Function pointer arguments and classes inheritance automatic cast

First of all sorry if the name of the question is not clear enough. I really have no idea on how to call this problem.
So I have a function pointer inside a class that works like a java callback that I invoke with some parameters like itself that is derived from a parent class like in this example:
class Parent;
using f_Call = void(*)(Parent*);
class Parent
{
public:
void setCallback(f_Call call)
{
mOnCall = call;
}
protected:
f_Call mOnCall = nullptr;
};
class Child1 : Parent
{
public:
void doSomething()
{
// some work..
if (mOnCall)
mOnCall(this);
}
};
void onCallExe(Parent* p)
{
Child1* child = (Child1*)p;
// do some more work...
}
int main()
{
Child1 child;
child.setCallback(onCallExe);
child.doSomething();
}
My question is if does c++ has a way of doing the cast from parent to children automatically in onCallExe so I don't have to do it for every function I call.
Thank you!
Don't use function pointers. Instead, you want std::function<void()> (yes, without arguments) and pass it a lambda with a captured object.
using f_Call = std::function<void()>;
class Parent {
public:
void setCallback(f_Call call) {
mOnCall = call;
}
protected:
f_Call mOnCall;
};
class Child1 : public Parent {
public:
void doSomething() {
// some work..
if (mOnCall)
mOnCall(); // no argument!
}
};
int main() {
Child1 child;
child.setCallback([&child](){ /* do whatever with the child */ });
child.doSomething();
}
If you want, you can hide creation of the lambda in a function template.
template <class Obj, class CB>
void setCallback (Obj& obj, CB cb) {
obj.setCallback([&obj](){cb(obj);});
}
and then pass the global setCallback template any old function with a Child argument.
void onCallExe(Child1& child) {
// do some more work...
}
Child1 child;
setCallback(child, onCallExe);
Curiously recurring template pattern might be an option. However, you'll create separate base classes for each derived one, so you couldn't use them polymorphically – unless you provided a separate, common base. If the recurring template function overwrites a virtual one in the base, you might end up at where you wanted to get:
struct Base
{
virtual ~Base() { }
virtual void f() = 0;
};
template <typename T>
struct Intermediate : Base
{
void f() override
{
if(callback)
callback(static_cast<T*>(this));
}
void setCallback(void(*c)(T*))
{
callback = c;
}
private:
void(*callback)(T*) = nullptr;
};
struct Derived : Intermediate<Derived>
{
};
void g(Derived*) { }
void demo()
{
Derived d;
d.setCallback(g);
d.f();
}
(If you don't need polymorphism, you can skip Base class – then f doesn't have to be virtual either.)
Solely if you wanted to set the callbacks via pointer or reference to Base, you are a bit in trouble, as you cannot have virtual template member functions. You could, though provide a free-standing helper function:
template <typename T>
void setCallback(Base& b, void(*callback)(T*))
{
dynamic_cast<Intermediate<T>&>(b).setCallback(callback);
}
The dynamic cast will throw a std::bad_cast if b is of inappropriate type – unfortunately a rather costly run-time thing, a safe way to let the compiler determine if pointed/referred object is of correct type (usually) is not possible.

C++ Static Polymorphism––Referencing Specialized Template Methods Overloaded In Derived Class From Base Class Pointer

I am implementing a variation of the observer pattern in C++. However, because of the nature of the nature of my project, it CANNOT USE ANY VIRTUAL MEMBER FUNCTIONS, as the aggregate overhead from vtable lookups and cache misses is unacceptable.
Were I to create interfaces via virtual member functions, I would trivially write the following:
template <class MessageType>
class MessageSubscriber {
public:
virtual void OnMessage(MessageType *message) = 0;
};
template <class MessageType>
class MessagePublisher {
public:
void AddSubscriber(MessageSubscriber<MessageType> *subscriber) {
subscribers.push_back(subscriber);
}
protected:
void Publish(MessageType *message) {
for (auto subscriber : subscribers)
subscriber.OnMessage(message);
}
private:
std::vector<MessageSubscriber<MessageType>*> subscribers;
};
Then, for example, I could have classes that implement MessageSubscriber for some MessageType, SafetyMessage, like so:
class SafetyMessageSubscriberA : public MessageSubscriber<SafetyMessage> {
public:
virtual void OnMessage(SafetyMessage *message) override {
/* process message */
}
};
class SafetyMessageSubscriberB : public MessageSubscriber<SafetyMessage> {
public:
virtual void OnMessage(SafetyMessage *message) override {
/* process message */
}
};
class SafetyMessagePublisher : public MessagePublisher<SafetyMessage> {
public:
void Run {
/* manipulate message data */
this->Publish(&message);
}
private:
SafetyMessage message;
};
This would get the job done, but, as emphasized earlier, the vtable lookup overhead is unacceptable in the context of the application despite the polymorphic convenience that it provides and is also needed for the application. Naturally, then, I tried several approaches centering around the static polymorphism that can be leveraged through templates.
I first tried to utilize CTRP, but it fails in this case because the pointers contained in MessagePublisher::subscribers must point to the same base class when MessagePublisher::Publish(MessageType *message) is called. Ergo, you could not have some CTRP pattern along the lines of MessageSubscriber<SafetyMessageSubscriberA>, MessageSubscriber<SafetyMessageSubscriberB>, as the template arguments would need to be the same for both objects to legally be allowed in MessagePublisher::subscribers.
My most recent attempt at the problem has lead me to try some variations of member function template specialization, albeit unsuccessfully. I have tried the following variation on the pattern interface:
class MessageSubscriber {
public:
template <class MessageType>
void OnMessage(MessageType *message);
};
class MessagePublisher {
public:
template <class MessageType>
void Publish(MessageType *message) {
for (auto subscriber: subscribers)
subscriber->OnMessage<MessageType>(message);
}
private:
std::vector<MessageSubscriber*> subscribers;
};
template<class MessageType>
void MessageSubscriber::OnMessageOnMessage(MessageType *message) {
/* "interface" call; do nothing */
}
With implementations such as:
class SafetyMessageSubscriberA : public MessageSubscriber {
public:
// declare for legal overload
template <class MessageType>
void OnMessage(MessageType *message);
};
class SafetyMessageSubscriberB : public MessageSubscriber {
public:
// declare for legal overload
template <class MessageType>
void OnMessage(MessageType *message);
};
template<>
void SafetyMessageSubscriberA::OnMessage<SafetyMessage*>OnMessage(SafetyMessage *message) {
/* process message */
}
template<>
void SafetyMessageSubscriberB::OnMessage<SafetyMessage*>OnMessage(SafetyMessage *message) {
/* process message */
}
When I tried this, however, MessagePublisher::Publish(SafetyMessage *message) would always call the generic MessageSubscriber::OnMessage(MessageType *m)implementation for the base class, not the ones that were implemented for the derived classes specific to SafetyMessage*.
Am I incorrectly specializing the function templates as intended, or is there another more efficient solution? I apologize in advance for any imprecise wording as it relates to the concepts of overloading and member template specialization.
You can cut out one level of indirection by using C-style function pointers in place of virtual functions. Thus, in the declaration of your base class you might have something like:
void (*) OnMessage (BaseClass *self, MessageType *message);
You then initialise this instance variable in each of your derived classes' constructors to point to the appropriate static member function, which in turn allows you to call it via a single indirect call (as opposed to two if you went via the vtable).
Finally, sadly, you will need to cast self in each of the target functions in the derived classes, which is the price you pay for all this trickery. Either that or cast the function signature when assigning the function pointer. I will post a fuller example if interested - let me know.

Workaround for specialization downcast

I tried to build a wrapper for a C module. The C module will do some CAN communication. To read something there is a read() function where a callback function pointer is passed with.
My idea was to make a Caller class where other classes (in example class A) can inherit from. I have now a problem in function "A::req()" with the comand "readObject()". To have no compiler errors I have to make a static_cast but then during excecution program will not work proberly. I already read that downcast in specialication can be dangerous. I guess my error is coming from that.
How could I solve my problem? Any ideas? Is there a design pattern which I should check?
Thanks.
class A : public Caller
{
public:
void req()
{
//readObject(&A::specializedCallback); // error from compiler
readObject(static_cast<Caller::CbkPtr_t>(&A::specializedCallback)); // has error during excecution, because of downcast?
}
void specializedCallback(void *data);
}
class Caller
{
public:
typedef void (CanIfcCaller::*CbkPtr_t)(void *data);
readObject(CbkPtr_t cbFcnt)
{
cbkFunction = cbFcnt;
Wrapper::readObject(this):
}
void callbackReadObject(void *data)
{
(this->*cbkFunction)(data);
}
private:
CbkPtr_t cbkFunction;
}
class Wrapper // to C function
{
public:
static void readObject(Caller* theCaller)
{
pCaller = theCaller;
read(&Wrapper::callbackReadObject);
}
static void callbackReadObject(void *data)
{
pCaller->callbackReadObject(data);
}
private:
Caller* pCaller;
}

C++, a number of classes derive from a class, all the derived classes use a class derived from something else but their base uses that clase's base

I'm sorry the title is so nasty, it's very hard to explain
class BaseState {
protected:
BaseState();
public:
void Some();
void Useful();
void Methods();
};
class UsefulState: public BaseState {
public:
void moreUsefulStuff();
};
class SomeUsefulBase {
protected:
SomeUsefulBase(BaseState* pState) { state = pState; }
void UsefulMethods() { state->Some(); }
void Andthings() { state->Useful(); }
public:
virtual void doSomething() = 0;
protected:
BaseState* state;
};
class SomethingUseful: public SomeUsefulBase {
public:
SomethingUseful(UsefulState* pState): SomeUsefulBase(pState) {
usefulState = pState;
}
virtual void doSomething() { usefulState->moreUsefulStuff();}
protected:
UsefulState* usefulState;
};
then:
SomethingUseful whatever(new UsefulState());
It's not important where things are allocated but there will be a lot of classes derived from SomethingUseful that will use a UsefulState however, all the member functions of SomeUsefulBase will use the state, but as a BaseState
I am hoping there is a better way than using two members (UsefulState and BaseState pointers in the definitions), I've thought of a union and a template, but that would be ugly.
I also don't want to litter my code with casts, I'm wondering if there is a nicer notation.
There will be one UsefulState per operation, and a large tree structure will be formed of various subclasses of SomethingUseful and/or subclasses of SomethingUsefulBase where a UsefulState pointer is expected.
Addendum:
Not sure what's up with SO's syntax highlighting! It seems to be using case to decide if it wants to colour things blue or not.... not sure how that works.
Addendum 2:
In the use this example is derived from there is one state per operation but many things derived from SomeUsefulBase, the derived classes will create each other to form a large tree structure (god I sound noobish) but will all require the use of the derived state.
That sounds like the standard "abstract factory"-type situation:
struct AbstractGadget { virtual ~AbstractGadget() {} };
struct AbstractWidget { virtual ~AbstractWidget() {} };
struct AbstractThingy { virtual ~AbstractThingy() {} };
struct AbstractFactory
{
virtual ~AbstractFactory() {}
virtual std::unique_ptr<AbstractGadget> make_gadget() = 0;
virtual std::unique_ptr<AbstractGadget> make_widget() = 0;
virtual std::unique_ptr<AbstractGadget> make_thingy() = 0;
};
Usage:
struct Gadget1 : AbstractGadget { /* ... */ };
struct Widget1 : AbstractWidget { /* ... */ };
struct Thingy1 : AbstractThingy { /* ... */ };
struct Factory1 : AbstractFactory
{
virtual std::unique_ptr<AbstractGadget> make_gadget()
{
return { new Gadget1; }
}
// ...
};
And so forth for Factory2 and Widget3 etc. There's plenty of potential for eliminating boilerplate code with templates here, too.
Consumers might be given an AbstractFactory & f and call f.make_gadget() etc. to create objects of a suitable type.

C++ Functor Callback Setup

Im following Lars Haendel's Functor tutorial on newty.de to setup a callback system. I am a bit confused however and I am hoping someone can assist me.
Here is my Functor template
#include <igameevents.h>
// Abstract Base Class (Functor)
class TBaseCallback
{
public:
// two possible functions to call member function. virtual cause derived
// classes will use a pointer to an object and a pointer to a member function
// to make the function call
virtual void operator()(IGameEvent *pEvent){}; // call using operator
virtual void Call(IGameEvent *pEvent) {}; // call using function
};
// Derived Template Class
template <class TClass> class TEventCallback : public TBaseCallback
{
private:
void (TClass::*funcPtr)(IGameEvent*); // pointer to member function
TClass* thisPtr; // pointer to object
public:
// constructor - takes pointer to an object and pointer to a member and stores them in two private variables
TEventCallback(TClass* _thisPtr, void(TClass::*_funcPtr)(const char*))
{ thisPtr = _thisPtr; funcPtr=_funcPtr; };
// override operator "()"
virtual void operator()(IGameEvent *pEvent)
{ (*thisPtr.*funcPtr)(pEvent); }; // execute member function
// override function "Call"
virtual void Call(IGameEvent *pEvent)
{ (*thisPtr.*funcPtr)(pEvent); }; // execute member function
};
What I want to do is basically allow other .dlls to use my HookGameEvent() function, and when a Game Event is called, I can run through a vector||list of my hooks, check if the event name matches, then execute the callbacks as needed. What is confusing me though is how I can store the callback in my HookEvent struct which looks like this.
std::vector<EventHook*> m_EventHooks;
struct EventHook
{
char *name;
EventHookMode mode;
//TEventCallback<IGameEvent*> pEventCallback;
};
I have it commented out for now, but im sure its obvious what im confused on and where I am screwing up. If anyone can provide any assistance it would be much appreciated.
Most people don't understand inheritance. Generally, derived classes are implementation details. The only time you utter their names are to construct them. Furthermore, virtual functions in a base should be private and pure, and should be completely inaccessible in derived classes, it's a design bug in C++ that this isn't enforced.
struct TBaseCallback
void operator()(IGameEvent *pEvent) { _Call(pEvent); };
void Exec(IGameEvent *pEvent) { _Call(PEvent); }
private:
virtual void _Call(IGameEvent *pEvent)=0;
};
struct EventHook
{
char *name;
EventHookMode mode;
TBaseCallback *p;
void dispatch(char *msg; IGameEvent *e) const {
if(strcmp(msg,name)==0) p->Exec(e);
}
};
With this design, it doesn't make any difference what is in classes derived from TBaseCallback, and nor should it. Only the abstraction should ever be publically visible. In normal code this is hard to enforce .. when you're using DLLs to get the derived classes it is absolutely mandatory because the set of derived classes is open/arbitrary/infinite/indeterminate (take your pick).
BTW: when you push this to more complex abstractions you will soon discover why Object Orientation is a broken concept. With DLL loaded derived classes, you simply cannot cheat with dynamic_cast switches (because they're closed/specific/finite/determinate).
The class that is going to do the callbacks should hold a list of Functor objects to be called. These would be your
std::vector<EventHook*> m_EventHooks;
Now the EventHook should have a virtual function:
struct EventHook
{
...
virtual void notifyMe();
}
Then everyone that is interested in getting notified will create his own implementation of the hook:
struct MyEventHook : public EventHook
{
virtual void notifyMe() { ... whatever I want to do in that case ... }
}
Through the wonders of polymorphism, when you then iterate over all elements of your m_EventHooks container and call notifyMe() for those, the correct class' version will be called.
The problem I see (and there could very well be others) is that in pEventCallback's type, the template parameter should be a class type but is actually a pointer type. One fix (without limiting what types the callback wraps) is to use the base type:
struct EventHook
{
char *name;
EventHookMode mode;
TBaseCallback* pCallback;
};
If there's more to TEventCallback's API, and it needs to be accessible through an EventHook, you should move the code in TEventCallback that deals with an object and its method into a separate subclass.
// Example EventCallback that takes other args
class EventCallback : public TBaseCallback {
public:
EventCallback();
EventCallback(const EventArgs& evtArgs);
// EventCallback specific methods ...
virtual EventArgs& args();
virtual const EventArgs& args() const;
}
/* TReturn allows for calling methods with a non-void return. Return value is ignored.
*/
template <class TClass, typename TReturn = void>
class TMethodCallback : public EventCallback
{
private:
typedef TReturn (TClass::*TMeth)(IGameEvent*);
TMeth funcPtr; // pointer to member function
TClass* thisPtr; // pointer to object
public:
// constructor - takes pointer to an object and pointer to a member and stores them in two private variables
TMethodCallback(TClass* _thisPtr, TMeth _funcPtr)
{ thisPtr = _thisPtr; funcPtr=_funcPtr; };
// override operator "()"
virtual void operator()(IGameEvent *pEvent)
{ (*thisPtr.*funcPtr)(pEvent); }; // execute member function
// override function "Call"
virtual void Call(IGameEvent *pEvent)
{ (*thisPtr.*funcPtr)(pEvent); }; // execute member function
};
Off-Topic
You might as well make the default implementation of TBaseCallback::Call call TBaseCallback::operator().
void TBaseCallback::Call(IGameEvent *pEvent) { this->operator()(pEvent); };
I think you will be getting a complicated compiler error because you are using T* instead of T in your template instantiation.
Try this:
struct EventHook
{
char *name;
EventHookMode mode;
TEventCallback<IGameEvent> pEventCallback;
};
should compile, if that what you want.