In my main.cpp I have something similar to the following:
void OnEventStart(int id)
{
// Do some stuff
}
This function is a callback, it is only triggered (by the main sdk that this is from) when an event has occured.
I now have this class:
class SomeClass {
public:
void OnEventStart(int id);
};
void SomeClass::OnEventStart(int id)
{
// Do some other stuff
}
Now I want to trigger void SomeClass::OnEventStart(int id) without doing something like this:
SomeClass class;
void OnEventStart(int id)
{
// Do some stuff
class.OnEventStart(id);
// AnotherClass.OnEventStart(id);
// Another.OnEventStart(id);
}
As you can imagine, using a method like this can easily clutter up the inital function/callback.
Your question is not very clear, but I'll assume the following:
You have some sort of callback handler that takes a void(*)(int).
In that case, if SomeClass is stateless, you can simply use a lambda wrapper:
my_framework_callback([]{ SomeClass{}.OnEventStart(id); });
If I misunderstood what you were asking, here's a different assumption:
SomeClass and similar types are stateless.
You're annoyed by having to instantiate SomeClass just to call one of its methods.
If that's the case, you can create a temporary instance of SomeClass on the spot:
void OnEventStart(int id)
{
SomeClass{}.OnEventStart(id);
AnotherClass{}.OnEventStart(id);
Another{}.OnEventStart(id);
}
If your question is instead...
"I have various classes with the same interface, and I want to call a function on all of them."
...then one possible solution would be using an abstract base class that provides .OnEventStart() = 0 and store an std::vector of pointers to that base class.
std::vector<std::unique_ptr<MyAbstractClass>> handlers;
void OnEventStart(int id)
{
for(auto& h : handlers)
h->OnEventStart(id);
}
Related
I am working on a C++ Arduino sketch that creates a GUI on an OLED display. I want to have buttons buttons that all do different things when you press them. In Java, I can simply override the method when creating an anonymous class like this:
class Example {
public void method() {
}
}
Example e = new Example() {
#Override
public void method() {
//do something
}
};
So my question is: Can I do this in an C++?
As arduino sketch are in fact C/C++, you could do the same as in Java.
class Button {
virtual void push() = 0;
}
class PowerButton : public Button {
virtual void push() {
shutdown();
}
}
Notice the virtual keyword, it's used to declare a method overidable, the "= 0" means pure virtual (the address of the method is 0). It simply says that this method is not implemented in this class, the class became abstract as in Java.
Also, the virtual keyword is not mandatory, but if you don't put it, C++ will just call the method of the given type and not from the real type.
Take a look there
But, the difference with Java is that you can't create an anonymous class directly in the code. Instead, maybe take a look for lambda.
For example, the class Button would became :
class Button {
public:
Button(const std::function<void()> &pushCallback) :
mPushCallback(pushCallback) {}
void push() { mPushCallback(); }
private:
const std::function<void()> mPushCallback;
And then the usage:
Button powerButton([]() {
powerOff();
});
Brackets are use to "capture" a variable, for example this, &str { myMethodInMyClass(str); }
Parenthesis are used to pass parameters
The std::function class take the function type as type parameter, a function that take a string as const ref and an int and that return an int will look like this : std::function<int(const std::string &, int)>
Let's say I have a parent class, Arbitrary, and two child classes, Foo and Bar. I'm trying to implement a function to insert any Arbitrary object into a database, however, since the child classes contain data specific to those classes, I need to perform slightly different operations depending on the type.
Coming into C++ from Java/C#, my first instinct was to have a function that takes the parent as the parameter use something like instanceof and some if statements to handle child-class-specific behavior.
Pseudocode:
void someClass(Arbitrary obj){
obj.doSomething(); //a member function from the parent class
//more operations based on parent class
if(obj instanceof Foo){
//do Foo specific stuff
}
if(obj instanceof Bar){
//do Bar specific stuff
}
}
However, after looking into how to implement this in C++, the general consensus seemed to be that this is poor design.
If you have to use instanceof, there is, in most cases, something wrong with your design. – mslot
I considered the possibility of overloading the function with each type, but that would seemingly lead to code duplication. And, I would still end up needing to handle the child-specific behavior in the parent class, so that wouldn't solve the problem anyway.
So, my question is, what's the better way of performing operations that where all parent and child classes should be accepted as input, but in which behavior is dictated by the object type?
First, you want to take your Arbitrary by pointer or reference, otherwise you will slice off the derived class. Next, sounds like a case of a virtual method.
void someClass(Arbitrary* obj) {
obj->insertIntoDB();
}
where:
class Arbitrary {
public:
virtual ~Arbitrary();
virtual void insertIntoDB() = 0;
};
So that the subclasses can provide specific overrides:
class Foo : public Arbitrary {
public:
void insertIntoDB() override
// ^^^ if C++11
{
// do Foo-specific insertion here
}
};
Now there might be some common functionality in this insertion between Foo and Bar... so you should put that as a protected method in Arbitrary. protected so that both Foo and Bar have access to it but someClass() doesn't.
In my opinion, if at any place you need to write
if( is_instance_of(Derived1) )
//do something
else if ( is_instance_of(Derived2) )
//do somthing else
...
then it's as sign of bad design. First and most straight forward issue is that of "Maintainence". You have to take care in case further derivation happens. However, sometimes it's necessary. for e.g if your all classes are part of some library. In other cases you should avoid this coding as far as possible.
Most often you can remove the need to check for specific instance by introducing some new classes in the hierarchy. For e.g :-
class BankAccount {};
class SavingAccount : public BankAccount { void creditInterest(); };
class CheckingAccount : public BankAccount { void creditInterest(): };
In this case, there seems to be a need for if/else statement to check for actual object as there is no corresponsing creditInterest() in BanAccount class. However, indroducing a new class could obviate the need for that checking.
class BankAccount {};
class InterestBearingAccount : public BankAccount { void creditInterest(): } {};
class SavingAccount : public InterestBearingAccount { void creditInterest(): };
class CheckingAccount : public InterestBearingAccount { void creditInterest(): };
The issue here is that this will arguably violate SOLID design principles, given that any extension in the number of mapped classes would require new branches in the if statement, otherwise the existing dispatch method will fail (it won't work with any subclass, just those it knows about).
What you are describing looks well suited to inheritance polymorphicism - each of Arbitrary (base), Foo and Bar can take on the concerns of its own fields.
There is likely to be some common database plumbing which can be DRY'd up the base method.
class Arbitrary { // Your base class
protected:
virtual void mapFields(DbCommand& dbCommand) {
// Map the base fields here
}
public:
void saveToDatabase() { // External caller invokes this on any subclass
openConnection();
DbCommand& command = createDbCommand();
mapFields(command); // Polymorphic call
executeDbTransaction(command);
}
}
class Foo : public Arbitrary {
protected: // Hide implementation external parties
virtual void mapFields(DbCommand& dbCommand) {
Arbitrary::mapFields();
// Map Foo specific fields here
}
}
class Bar : public Arbitrary {
protected:
virtual void mapFields(DbCommand& dbCommand) {
Arbitrary::mapFields();
// Map Bar specific fields here
}
}
If the base class, Arbitrary itself cannot exist in isolation, it should also be marked as abstract.
As StuartLC pointed out, the current design violates the SOLID principles. However, both his answer and Barry's answer has strong coupling with the database, which I do not like (should Arbitrary really need to know about the database?). I would suggest that you make some additional abstraction, and make the database operations independent of the the data types.
One possible implementation may be like:
class Arbitrary {
public:
virtual std::string serialize();
static Arbitrary* deserialize();
};
Your database-related would be like (please notice that the parameter form Arbitrary obj is wrong and can truncate the object):
void someMethod(const Arbitrary& obj)
{
// ...
db.insert(obj.serialize());
}
You can retrieve the string from the database later and deserialize into a suitable object.
So, my question is, what's the better way of performing operations
that where all parent and child classes should be accepted as input,
but in which behavior is dictated by the object type?
You can use Visitor pattern.
#include <iostream>
using namespace std;
class Arbitrary;
class Foo;
class Bar;
class ArbitraryVisitor
{
public:
virtual void visitParent(Arbitrary& m) {};
virtual void visitFoo(Foo& vm) {};
virtual void visitBar(Bar& vm) {};
};
class Arbitrary
{
public:
virtual void DoSomething()
{
cout<<"do Parent specific stuff"<<endl;
}
virtual void accept(ArbitraryVisitor& v)
{
v.visitParent(*this);
}
};
class Foo: public Arbitrary
{
public:
virtual void DoSomething()
{
cout<<"do Foo specific stuff"<<endl;
}
virtual void accept(ArbitraryVisitor& v)
{
v.visitFoo(*this);
}
};
class Bar: public Arbitrary
{
public:
virtual void DoSomething()
{
cout<<"do Bar specific stuff"<<endl;
}
virtual void accept(ArbitraryVisitor& v)
{
v.visitBar(*this);
}
};
class SetArbitaryVisitor : public ArbitraryVisitor
{
void visitParent(Arbitrary& vm)
{
vm.DoSomething();
}
void visitFoo(Foo& vm)
{
vm.DoSomething();
}
void visitBar(Bar& vm)
{
vm.DoSomething();
}
};
int main()
{
Arbitrary *arb = new Foo();
SetArbitaryVisitor scv;
arb->accept(scv);
}
I have one problem. I am writing my program on C++ language. I have one problem. I need to set signal handler for my process. As the signal is related with the process on system level I have faced the problem.
My program consists of several classes. They are connected together. But it doesn't matter in this case.
The problem is that I need access to member and methods of the class from my signal handler. For instance, I have a class named Foo at it has some members and methods.
So from my handler I need to call its function and change members.
I understand that compiler should know that this class instances will exist during all program execution.
I have tried to set static member class Foo instance in another class , but this didn't solve the problem.
I have no idea what is the correct approach for doing this. Please explain how to correctly implement signal handling in such case.
Here is an example of my code:
class MyContainer
{
private:
std::vector<Foo> container;
public:
int removeFromContainer(Foo* aFoo) {
// DO some stuff
return RESULT_CODE;
}
int addToContainer(Foo* aFoo) {
// DO some stuff
return RESULT_CODE;
}
};
Here is my Main class
class MainClass
{
private:
int member;
public:
void mainLoop(char* args) {
signal(SIGCHLD, &signalHandler);
}
};
Here is my function for signal handling
void static signalHandler_child(int p)
{
this->myContainerInstance->addToContainer(new Foo);
}
A static method is not so different from a global function. If you need to access instance members of a class, your signal handler should take an instance pointer/reference as argument.
Something like this
class Foo
{
private:
int member;
public:
static int Handler(Foo* aFoo) { return aFoo->member; }
};
I want to be able to add commands to the manager instance and associate those commands with invoking public methods from both class A and class B when they're executed. I know that in order to achieve this the class Command should have a pointer to a class member function instead of a regular function (void (T::*Handler)() instead of void(*Handler)() ), but I found myself lost in how exactly I can achieve this. I have the following code:
typedef void (*Handler)();
class Command {
public:
Command(char*, Handler);
private:
char* name;
Handler handler;
};
class CommandManager {
public:
CommandManager();
void addCommand(Command*);
void execute(char* commandName);
private:
Command** commands;
}
// implementation, copy constructor and destructor should be ignored at this point since they do
// not affect directly the question I'm trying to find an answer for.
I have another two classes. Let's say they're class A and class B, both having methods with return type void
and with no params. I also have class C which contains member variables of type pointers to A and B:
class C {
public:
// some public stuff here
private:
A* a;
B* b;
CommandManager* manager;
}
Note: It might be easier to introduce inheritance and abstract class but this is something I am limitted not to use(do not ask why :) ), so is there any way to do what I want?
The "best" solution:
typedef std::function<void()> Handler;
//std::function<void()> is the magic bit you were asking about
class Command {
public:
Command(const std::string& name, Handler) {}
private:
std::string name;
Handler handler;
};
class CommandManager {
public:
CommandManager();
void addCommand(std::unique_ptr<Command>);
void execute(const std::string& commandName);
private:
std::vector<Command> commands;
};
and then functionoids go like this
struct A {
void operator()() {std::cout << "A";}
};
Command ACommand = {"A", A()};
//constructs a temporary A,
//then a temporary std::function<void()> is constructed which stores the A
//then the Command stores this function.
struct B {
void named_function() {std::cout << "B";}
};
B bobj;
Command BCommand = {"B", std::bind(&B::named_function, &bobj)};
//bind constructs a functionoid binding the bobj as the "this" of the member function
//then a temporary std::function<void()> is constructed which stores the functionoid
//then the Command stores this function.
The problem is the this pointer passed implicitly to every member function. This makes the signature of the functions of A different from those of B.
Without using templates and inheritance, the easiest way would be to declare the functions of A and B as static. Then, there is no this pointer, and the functions can be assigned to the function pointer handler.
Because it's not likely to be powerful enough, here another way, but I must say it's a kludge, it would really be better to use inheritance.
Define
typedef Handler void (*Handler)(void *);
and implement the static command handlers as follows
void A::doit(void *arg)
{
A *newthis = (A*)arg;
newthis->UseMembersOfA();
}
In my design, there is a class which reads information from file. The read info represents a job (for simplicity, it's an integer, which is "job id"). The file reader class can accept objects which can handle such a job. Now my idea was, to make an Interface, e.g. "IJobHandler" which has a pure virtual function "DoJob()" and then you can call something like
FileReader fr;
Class1 c1; // has a base class IAcceptor with virtual method HandleJobId()
Class2 c2; // has a base class IAcceptor with virtual method HandleJobId()
fr.Register(c1);
fr.Register(c2);
fr.doJob(1); // calls c1.HandleJobId()
fr.doJob(2); // class c2.HandleJobId()
This would work fine. But what happens, if some class can handle two or more job ids? But there is only one method which this class can implement (HandleJobId()). Wouldn't the following be nice:
fr.Register(c1, c1::Handle_1()) or something like that?
Maybe my intention is not very clear right now. But you will se it on the bigger code example below. Sorry for the big code block, but I don't know how to explain it that exactly...
class IAcceptable
{
public:
// interface; implementors should return map of job-ids (int)
// and a kind of pointer to a method which should be called to
// handle the job.
virtual std::map<int, SOME_KIND_OF_FUNCTION_POINTER> GetJobIds() const = 0;
};
class Class12 : public IAcceptable
{
public:
void Handle_1(){} // method to handle job id 1
void Handle_2(){} // method to handle job id 2
virtual std::map<int, SOME_KIND_OF_FUNCTION_POINTER> GetJobIds() const
{
std::map<int, SOME_KIND_OF_FUNCTION_POINTER> intToMethodMap;
// return map, which says: "I can handle job id 1, by calling Handle_1(), so I give you c12 pointer to this method"
// (same thing for job id 2 and Handle_2())
intToMethodMap.insert(std::pair<int, SOME_KIND_OF_FUNCTION_POINTER>(1, POINTER_TO_Handle_1);
intToMethodMap.insert(std::pair<int, SOME_KIND_OF_FUNCTION_POINTER>(2, POINTER_TO_Handle_2);
return intToMethodMap;
}
};
class Class34 : public IAcceptable
{
void Handle_3(){} // method to handle job id 3
void Handle_4(){} // method to handle job id 4
virtual std::map<int, SOME_KIND_OF_FUNCTION_POINTER> GetJobIds() const
{
std::map<int, SOME_KIND_OF_FUNCTION_POINTER> intToMethodMap;
// return map, which says: "I can handle job id 3, by calling Handle_3(), so I give you c12 pointer to this method"
// (same thing for job id 4 and Handle_4())
intToMethodMap.insert(std::pair<int, SOME_KIND_OF_FUNCTION_POINTER>(3, POINTER_TO_Handle_3);
intToMethodMap.insert(std::pair<int, SOME_KIND_OF_FUNCTION_POINTER>(4, POINTER_TO_Handle_4);
return intToMethodMap;
}
};
class FileReader
{
public:
// register an IAcceptable
// and add its handlers to the local list
void Register(const IAcceptable& acc)
{
m_handlers.insert(acc.GetJobIds());
}
// if some job is to do, search for the job id and call
// the found function
void doSomeJob(int i)
{
std::map<int, SOMEFUNCTION>::iterator specificHandler = m_handlers.find(i);
// call here (specificHandler->second)()
}
private:
std::map<int, SOMEFUNCTION> m_handlers;
};
int main()
{
Class12 c12; // can handle job id 1 and 2
Class34 c34; // can handle job id 3 and 4
FileReader fr;
fr.Register(c12);
fr.Register(c34);
fr.doSomeJob(1); // should lead to this call: c12->Handle_1()
fr.doSomeJob(2); // c12->Handle_2();
fr.doSomeJob(3); // c34->Handle_3();
fr.doSomeJob(4); // c34->Handle_4();
}
Well, maybe the design is my problem and someone can give me a hint how to make it better :)
Here's a complete example:
class IAcceptable;
class DelegateBase
{
public:
virtual void Call() = 0;
};
template <class Class> class Delegate: public DelegateBase
{
public:
typedef void (Class::*Function)();
Delegate(Class* object, Function f): func(f) {}
virtual void Call() { (object->*func)(); }
private:
Class* object;
Function func;
};
class IAcceptable
{
public:
// interface; implementors should return map of job-ids (int)
// and a kind of pointer to a method which should be called to
// handle the job.
virtual std::map<int, DelegateBase*> GetJobIds() = 0;
};
class Class12 : public IAcceptable
{
public:
void Handle_1(){} // method to handle job id 1
void Handle_2(){} // method to handle job id 2
virtual std::map<int, DelegateBase*> GetJobIds()
{
std::map<int, DelegateBase*> intToMethodMap;
// return map, which says: "I can handle job id 1, by calling Handle_1(), so I give you c12 pointer to this method"
// (same thing for job id 2 and Handle_2())
intToMethodMap.insert(std::pair<int, DelegateBase*>(1, new Delegate<Class12>(this, &Class12::Handle_1)));
intToMethodMap.insert(std::pair<int, DelegateBase*>(2, new Delegate<Class12>(this, &Class12::Handle_2)));
return intToMethodMap;
}
};
class Class34 : public IAcceptable
{
void Handle_3(){} // method to handle job id 3
void Handle_4(){} // method to handle job id 4
virtual std::map<int, DelegateBase*> GetJobIds()
{
std::map<int, DelegateBase*> intToMethodMap;
// return map, which says: "I can handle job id 3, by calling Handle_3(), so I give you c12 pointer to this method"
// (same thing for job id 4 and Handle_4())
intToMethodMap.insert(std::pair<int, DelegateBase*>(3, new Delegate<Class34>(this, &Class34::Handle_3)));
intToMethodMap.insert(std::pair<int, DelegateBase*>(4, new Delegate<Class34>(this, &Class34::Handle_4)));
return intToMethodMap;
}
};
class FileReader
{
public:
// register an IAcceptable
// and add its handlers to the local list
void Register(IAcceptable& acc)
{
std::map<int, DelegateBase*> jobIds = acc.GetJobIds();
m_handlers.insert(jobIds.begin(), jobIds.end());
}
// if some job is to do, search for the job id and call
// the found function
void doSomeJob(int i)
{
std::map<int, DelegateBase*>::iterator specificHandler = m_handlers.find(i);
specificHandler->second->Call();
}
private:
std::map<int, DelegateBase*> m_handlers;
};
int _tmain(int argc, _TCHAR* argv[])
{
Class12 c12; // can handle job id 1 and 2
Class34 c34; // can handle job id 3 and 4
FileReader fr;
fr.Register(c12);
fr.Register(c34);
fr.doSomeJob(1); // should lead to this call: c12->Handle_1()
fr.doSomeJob(2); // c12->Handle_2();
fr.doSomeJob(3); // c34->Handle_3();
fr.doSomeJob(4); // c34->Handle_4();
return 0;
}
To call a member function we need an object; so your maps should contain not simply method pointers, but something that can encapsulate a complete call: an object + a method pointer. That something is Delegate here.
To make sure that the method is called correctly even if it's defined in a subclass, we need to store both the derived object and the method pointer type-correctly (no casting). So we make Delegate a template, with the derived class as its parameter.
This means that delegates based on methods of different subclasses are incompatible, and cannot be put into a map. To work around this we introduce a common base class, DelegateBase, and the virtual function Call(). Call() can be called without knowing the exact type of stored object / method, and it will be dispatched to a type-correct implementation. Now we can store DelegateBase* pointers in the map.
Also check out boost::function and boost::bind, they provide a generalization for the above, and I think they could also be used to your purposes.
There are several solutions to this sort of problem.
If you have a class which can handle several different jobs, in separate
functions, the simplest solution is to wrap it, several types, e.g.:
class JobsOneAndTwo
{
public:
void doJobOne();
void doJobTwo();
};
class JobOne : public AbstractJob, JobsOneAndTwo
{
public:
virtual void doJob() { doJobOne(); }
};
class JobTwo : public AbstractJob, JobOneAndTwo
{
public:
virtual void doJob() { doJobTwo(); }
};
If this occurs often in the set of jobs, you can create a template (over
two or moer member function pointers) to generate the individual wrapper
functions.
Alternatively, you can dispatch on a data member of the class:
class JobOneAndTwo : public AbstractJob
{
int myJob;
public:
JobOneAndTwo(int id) : myJob( id ) {}
void JobOne();
void JobTwo();
virtual void doJob()
{
switch ( myJob ) {
case 1:
JobOne();
break;
case 2:
JobTwo();
break;
}
};
In this case, you instantiate the class twice, each time passing a
different argument to the constructor.
In most of the cases I've seen, when one class can handle two jobs, it's
because the two jobs differ only in some parameters; this is really just
a variant on the second solution above, except that you don't switch to
call different member functions, you simply use the parameters (passed
into the constructor) in the basic function.
More generally, don't forget that your concrete job classes can have
data, and their behavior can be modified by such data. And that you can
register multiple instances of a single class, with different data.
So you say that you have many handlers, each of which can handle an arbitrary number of job IDs, and you want to register an arbitrary number of handlers and let all of them which apply handle a given job.
To that end, let every handler implement this interface:
struct Handler
{
virtual bool canHandle(job_id_t id) const = 0;
virtual void doJob(job_it_t id) = 0;
};
To register a handler, simply store a pointer in a container:
std::vector<Handler*> handlers;
Then, if you need to do a job, iterate the container and dispatch:
handleJob(job_it_t id)
{
for (std::vector<Handler*>::iterator it = handlers.begin(), end = handlers.end(); it != end; ++it)
{
if ((*it)->canHandle(id))
(*it)->doJob(id);
}
}
typedef void (IAccaptable::*SOME_KIND_OF_FUNCTION_POINTER)();
...
Register(1, (SOME_KIND_OF_FUNCTION_POINTER)(&Class12::Handle1));
Warning: this C-style cast will only work with single inheritance. (Well, actually the cast would compile just fine with multiple inheritance too, but when calling (derivedObject->*funcPtr)() with a funcPtr that points at a member function of a non-first base class, then it would be called without the derivedObject pointer having been properly adjusted to point at the proper subobject belonging to that base, most probably resulting in a crash.)
A better, but more complicated solution would be to register small caller objects instead of member function pointers. When calling the handler functions, these caller objects could appropriately cast the target object.
class CallerBase
{
public:
virtual void Call(Base* object) = 0;
};
template <class Derived>
struct Caller: public CallerBase
{
public:
typedef void (Derived::*Function)();
Caller(Function f): func(f) {}
virtual void Call(Base* object)
{
Derived* derived = static_cast<Derived*>(object);
(derived->*func)();
}
private:
Function func;
};
Register(1, new Caller<Derived>(&Derived::F));
Then your map would contain CallerBase* pointers, and once you find the proper caller, you'd do caller->Call(object). If object in this call is a Derived*, then it will be implicitly cast to Base*, but the virtual Caller<Derived>::Call() function will cast it back to Derived* before actually calling the method.
Method pointers can be a lot of fun.
I don't want to self promote myself but check out my guide on them I wrote back in school.
http://nicolong.com/code-examples/menu-object-tutorial
Might help a little.