I have the following Class structure:
class WiFiHandler{
public:
void doWiFiStuff();
};
class Machine {
public:
void doSomething();
WiFiHandler _wifiHandler;
};
Now the WiFiHandler::doWiFiStuff()
receives a request which should trigger execution of Machine::doSomething()
.
However the Methods of Machine
are not known to WifiHandler
How does this Subclass WiFiHandler
execute Methods of its "Motherclass"?
CodePudding user response:
As many design issues, there are many ways to achieve similar result, each with some advatages and disadvatages.
Other answers to your question mention good soultions.
I'd like to propose a different one, that might fit some systems.
This solution might be good if the following 2 conditions (which are related) are met:
Machine
has multiple methods thatWiFiHandler
has to call.Machine
has a close association withWiFiHandler
and it's OK from other design constraints that it will be dependent on it (despite the fact that it is contained by it).
In this case, WiFiHandler
can hold a pointer to the Machine
containing it.
In order to solve the problem of circular #includes, we can use a forward declaration.
Note that WiFiHandler.cpp includes Machine.h and thus can use any public method of Machine
for its own implementation.
Code example:
// WiFiHandler.h:
class Machine; // forward declaration
class WiFiHandler {
Machine * m_pMyMachine;
public:
WiFiHandler(Machine * pMyMachine) : m_pMyMachine(pMyMachine) {}
void doWiFiStuff();
};
// Machine.h:
#include "WiFiHandler.h"
class Machine {
public:
Machine() : _wifiHandler(this) {}
void doSomething();
WiFiHandler _wifiHandler;
};
// WiFiHandler.cpp:
#include "WiFiHandler.h"
#include "Machine.h"
void WiFiHandler::doWiFiStuff()
{
m_pMyMachine->doSomething();
// ...
}
// Machine.cpp:
#include "Machine.h"
void Machine::doSomething()
{
// Do the machine stuff ...
}
CodePudding user response:
Neither of those is a subclass or "parent" of the other - there is no inheritance.
The WiFiHandler
is just a member of Machine
and has no knowledge of any Machine
's existence.
You need to give the WiFiHandler
something to call in that function, and it's usually useful to make this more general than a specific Machine
instance.
For instance, a callback function:
class WiFiHandler{
public:
WiFiHandler(std::function<void()> fun) : doIt(fun) {}
void doWiFiStuff() { doIt(); }
private:
std::function<void()> doIt;
};
class Machine {
public:
Machine() : _wifiHandler([this]() { doSomething(); }) {}
void doSomething() {}
WiFiHandler _wifiHandler;
};
This way, WiFiHandler
doesn't need to care about changes to Machine
or whether one exists at all.
CodePudding user response:
Change doWiFiStuff()
to
template< class R, class... Args >
void doWiFiStuff(std::function<R(Args...)> thing_to_do, Args... args);
so you can pass any function along to be called.