Callback definition is incompatible - c++

I use a library which has these definitions
typedef void (*CallbackFunction) (ESPRotary&);
void ESPRotary::setChangedHandler(CallbackFunction f) { ... }
When I try to use the setChangedHandler function I get an issue that the definition of my callback is wrong.
#pragma once
#include "ESPRotary.h"
class MyUsermod : public Usermod
{
private:
ESPRotary r = ESPRotary(13, 12);
public:
void rotate(ESPRotary &r)
{
Serial.println(r.getPosition());
}
void setup()
{
// argument of type "void (MyUsermod::*)(ESPRotary &r)" is incompatible
// with parameter of type "ESPRotary::CallbackFunction"C/C++(167)
r.setChangedHandler(rotate);
}
};
What am I doing wrong?

The callback function needs to be defined statically when defined inside the class:
class MyUsermod : public Usermod
{
private:
ESPRotary r = ESPRotary(13, 12);
public:
/* Callback function "static" defined */
static void rotate(ESPRotary &r)
{
Serial.println(r.getPosition());
}
void setup()
{
r.setChangedHandler(rotate);
}
};
References
Why callback functions needs to be static when declared in class?

void rotate(ESPRotary &r)
This is not a function. This is a (non-static) class method. This is declared as a member of class MyUsermod, something that's completely different from declaring a function named rotate() is some randomly-chosen .cpp file, with no further context.
Class methods require instances of classes to be invoked for. The type of rotate is
void (MyUsermod::*) (ESPRotary&)
and not
void (*) (ESPRotary&)
and this answers the reason for the compilation error, and the type mismathc.
As far as how to fix it, there is no uniform solution for every instance of this issue. It depends entirely on how these objects are used in the rest of your program. The most flexible solution is to change CallbackFunction to be the correct type, and then decide whose class instance's method will be invoked in the code that invokes the callback.

Related

Access base class variable from child static function

class A
{
public:
void init();
void method1();
void method2();
private:
bool _var1 = false;
bool _var2 = false;
};
class B : public A
{
public:
static void method3();
};
B::method3()
{
_var1 = false
}
If I call method3, I get the expected error "invalid use of member 'A::_var1' in static member function".
I have many classes which need to be static (have static functions), and many of the common variables and properties I need to inherit from a base class for code tidiness. What's the best solution for this problem?
Point me in the right direction, thank you.
a static function is not associated with an object hence cannot access class members.
see reference for more details.
you may need to pass an object instance as a function argument if that static function requires to use one e.g.
B::method3(B& b)
{
// do something with b
if b.isConnected() ) {}
}
bool B::isConnected(){return _isconnected;}

how do i inherit my abstract class?

I am new to c++ and currently learning inheritance. I am not sure how to properly inherit my abstract class MapItem, I keep receiving these errors ..
error snippet
hidden overloaded virtual function 'MapItem::tick' declared here:
different qualifiers (const vs none)
virtual void tick() const = 0;
Undefined symbols for architecture x86_64:
"Residential::Residential()"
It is also claiming that my class Residential is an abstract class.
The program only successfully compiles and runs when I add the const keyword to the tick() function. But quiet obviously, this is a problem because tick() needs to operate on some class member variables.
I properly included all the files and my make file is targeting all the correct files, which makes this error out of my understanding.
map_item.h
// abstract class
class MapItem {
...
virtual void tick() const = 0;
}
residential.h
#ifndef RESIDENTIAL_H
#define RESIDENTIAL_H
#include "map_item.h"
class Residential : public MapItem {
private:
int capacity;
double taxRevenue;
public:
Residential();
virtual ~Residential();
void tick();
double collectTaxes();
};
#endif
residential.cpp
#include "residential.h"
Residential::Residential() {
capacity = 1;
taxRevenue = 0.0;
}
Residential::~Residential() {}
void Residential::tick() {
}
double Residential::collectTaxes() {
taxRevenue = 0.0;
return taxRevenue;
}
Your problem's simply that in Residential you declare and define tick as follows:
void Residential::tick()
...while the abstract base has...
virtual void tick() const = 0;
You should add the const to Residential::tick, or remove it from Mapitem::tick, so they're consistent. You say...
The program only successfully compiles and runs when I add the const keyword to the tick() function. This is a problem because tick() needs to operate on some class member variables.
...so it sounds like removing it is what you want to do.
It's also a good idea to add override to Residential::tick() so the compiler's obliged to verify that it matches MapItem::tick():
void Residential::tick() [const] override
Declaring a member method results in a function declaration that takes an implicit this pointer as a first parameter.
So a method void Residential::tick() (without the const at the end) results in a function like void Residential::tick(Residential* this).
Now adding the const at the end void Residential::tick() const can then be understood as a declaration with a const this pointer:
void Residential::tick(const Residential* this)
so, when you declare void Residential::tick() const in base class and then declare void Residential::tick() in derived class, the function signatures donot match and compiler throws an error.
So, decide which signature you need(const qualified/non const) and make sure both the signatures match.

How to store a function in a member of class? (Using function as callback)

I want to store a function as a class member and call it inside the class? Pretty much like a callback function. My class draw a document but every document must drawn differently. So I want to assign a function (written outside of the class) into one of the members of the class and then call it when I want to draw the document.
This function mostly is responsible for transforming objects according to each specific document.
Here is my class:
class CDocument
{
public:
CDocument();
~CDocument();
void *TransFunc();
}
void Transform()
{
}
int main()
CDocument* Doc = new CDocument();
Doc->TransFunc = Transform();
}
I know that this is probably simple question, but I couldn't find the answer by googling or searching SO.
I think, this is what you might want. Please get back to me if you have questions.
class CDocument
{
public:
CDocument():myTransFunc(NULL){}
~CDocument();
typedef void (*TransFunc)(); // Defines a function pointer type pointing to a void function which doesn't take any parameter.
TransFunc myTransFunc; // Actually defines a member variable of this type.
void drawSomething()
{
if(myTransFunc)
(*myTransFunc)(); // Uses the member variable to call a supplied function.
}
};
void Transform()
{
}
int main()
{
CDocument* Doc = new CDocument();
Doc->myTransFunc = Transform; // Assigns the member function pointer to an actual function.
}
You need to use a Pointer to member function.
typedef void (CDocument::*TransFuncPtr)();
And then you can use TransFuncPtr as an type.
With your edit It seems like you just need a Pointer to a Free function.
Here is a small working sample.
#include<iostream>
#include<string>
typedef void (*TransFuncPtr)();
class Myclass
{
public:
TransFuncPtr m_funcPtr;
};
void doSomething(){std::cout<<"Callback Called";}
int main()
{
Myclass obj;
obj.m_funcPtr = &doSomething;
obj.m_funcPtr();
return 0;
}
The C declaration syntax, inherited by C++, is tricky.
Your declaration
void *TransFunc();
is actually the same as
void* TransFunc();
which declares a function returning a pointer, and not a pointer to a function.
To have the * bind to the declared name, and not to the type, you have to use an extra set of parenthesis
void (*TransFunc)();

class function that generates its own objects

I want to write a class for some use. I want to call a function (say generate) of this class which will generate two objects of this same class. These two objects will call other function of the class.
Can anyone tell me how to do this?
I want it in C++
Class Example{
public:
generate();
other_func();
}
int main()
{
Example generate();
}
Now this generate function should create two object of Example and will call other_func();
Well, from your description it would sound very easy:
struct Example
{
public:
static void generate() { Example e1, e2; e1.other_fun(); e2.other_fun(); }
void other_fun() { }
};
You can use factory methods to generate objects of specified class. Then the created objects based on the business logic processing can invoke other methods.
The only member functions of a class that can be called without an existing member of a class are static member functions. This is a more in depth topic, please see http://www.cprogramming.com/tutorial/statickeyword.html
So here I create a foo that does what you seem to have asked for and returns the foos:
class foo
{
public:
static void generate()
{
foo Temp1;
foo Temp2;
Temp1.bar();
Temp2.bar();
}
void bar()
{
}
};
edit: I removed the return type, per request
edit: I removed the return type completely, and correctly this time. But now I haven't test compiled the code.

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.