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"?
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 that WiFiHandler has to call.
Machine has a close association with WiFiHandler 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 ...
}
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.
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.
Related
I'm somewhat new to the more advanced features of C++. Yesterday, I posted the following question and I learned about virtual inheritance and the dreaded diamond of death.
Inheriting from both an interface and an implementation C++
I also learned, through other links, that multiple inheritance is typically a sign of a bad code design and that the same results can usually be better achieved without using MI. The question is... I don't know what is a better, single-inheritance approach for the following problem.
I want to define an Interface for two types of Digital Points. An Input Digital Point and an Output Digital Point. The Interface is to be slim, with only what's required to access the information. Of course, the vast majority of properties are common to both types of digital points. So to me, this is a clear case of Inheritance, not Composition.
My Interface Definitions look something like this:
// Interface Definitions
class IDigitalPoint
{
public:
virtual void CommonDigitalMethod1() = 0;
};
class IDigitalInputPoint : virtual IDigitalPoint
{
public:
virtual void DigitialInputMethod1() = 0;
};
class IDigitalOutputPoint : virtual IDigitalPoint
{
public:
virtual void DigitialOutputMethod1() = 0;
};
My implementations look like this:
// Implementation of IDigitalPoint
class DigitalPoint : virtual public IDigitalPoint
{
public:
void CommonDigitalMethod1();
void ExtraCommonDigitalMethod2();
}
// Implementation of IDigitalInputPoint
class DigitalInputPoint : public DigitalPoint, public IDigitalInputPoint
{
public:
void DigitialInputMethod1();
void ExtraDigitialInputMethod2();
}
// Implementation of IDigitalOutputPoint
class DigitalOutputPoint : public DigitalPoint, public IDigitalOutputPoint
{
public:
void DigitialOutputMethod1();
void ExtraDigitialOutputMethod2();
}
So how could I reformat this structure, to avoid MI?
"multiple inheritance is typically a sign of a bad code design" - parents that are pure interfaces are not counted in regards to this rule. Your I* classes are pure interfaces (only contain pure virtual functions) so you Digital*Point classes are OK in this respect
(Multiple) inheritance and interfaces tend to needless complications of simple relations.
Here we need only a simple structure and few freestanding functions:
namespace example {
struct Point { T x; T y; }
Point read_method();
void write_method(const Point&)
void common_method(Point&);
void extra_common_method(Point&);
} // example
The common_method might be a candidate for a member function of Point.
The extra_common_method, which is not so common, might be a candidate for another class encapsulating a Point.
This is exactly the situation in which the standard library does use virtual inheritance, in the std::basic_iostream hierarchy.
So, it may be the rare case where it genuinely makes sense.
However, this depends on exactly the fine details you've removed for clarity, so it isn't possible to say for certain whether a better solution exists.
For example, why is an input point different from an output point? A DigitalPoint sounds like a thing with properties, that might be modeled by a class. A DigitalInputPoint, however, just sounds like ... a DigitalPoint somehow coupled to an input source. Does it have different properties? Different behaviour? What are they and why?
You can go to below link to understand more about multiple inheritance
Avoid Multiple Inheritance
Also, in your case, multiple inheritance makes sense!!.
You may use composition if you want.
Consider a different approach:
class DigitalPoint
{
public:
void CommonDigitalMethod1();
void ExtraCommonDigitalMethod2();
}
// Implementation of IDigitalInputPoint
class DigitalInputPoint
{
public:
void CommonDigitalMethod1();
void DigitialInputMethod1();
void ExtraDigitialInputMethod2();
}
// Implementation of IDigitalOutputPoint
class DigitalOutputPoint
{
public:
void CommonDigitalMethod1();
void DigitialOutputMethod1();
void ExtraDigitialOutputMethod2();
}
To be used like this:
template <class T>
void do_input_stuff(T &digitalInputPoint){
digitalInputPoint.DigitialInputMethod1();
}
You get an easier implementation with a clearer design and less coupling with most likely better performance. The only One downside is that the interface is implicitly defined by the usage. This can be mitigated by documenting what the template expects and eventually you will be able to do it in concepts to have the compiler check it for you.
Another downside is that you cannot have a vector<IDigitalPoint*> anymore.
Are you really sure that you need 3 interfaces?
class IDigitalPoint
{
public:
virtual void CommonDigitalMethod1() = 0;
};
enum class Direction : bool { Input, Output };
template <Direction direction>
class DigitalPoint : public IDigitalPoint
{
public:
void CommonDigitalMethod1() {}
void ExtraCommonDigitalMethod2() {}
virtual void DigitialMethod1() = 0;
};
class DigitalInputPoint : public DigitalPoint<Direction::Input>
{
public:
void DigitialInputMethod1() {}
void ExtraDigitialInputMethod2() {}
// This is like DigitialInputMethod1()
virtual void DigitialMethod1() override
{}
};
class DigitalOutputPoint : public DigitalPoint<Direction::Output>
{
public:
void DigitialOutputMethod1() {}
void ExtraDigitialOutputMethod2() {}
// This is like DigitialOutputMethod1()
virtual void DigitialMethod1() override
{}
};
You could use composition instead of inheritance. Live Example
If the child classes do not use functionality from DigitalPoint, then you can try using CRTP. It can be confusing if you don't understand CRTP, but it works like a charm when it fits properly. Live Example
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 a problem with interfaces and multiple inheritance. I hope to design my program such that one update call processes a variety of objects, with each behavioral 'building block' tucked away in a single function.
For example, I'd like to move a creature from point A to B in one place, regardless of whether it must perform pre/post move actions. But, my multiple inheritance scheme fails (below, with the bug rem'd), making me think I'd need to duplicate code somewhere.
Clearly I don't understand this well enough! (but I'm working hard to learn it)
Q1. Why can't IPhysics::Move 'see' Creature::Move(), in the CreatureAirborne class?
Q2. Am I completely missing the proper usage of interfaces and/or multiple inheritance? If so, any guidance is appreciated!
#include <deque>
#include <memory>
class IGameObject
{
public:
virtual ~IGameObject() {}
virtual void Update() = 0;
};
class IPhysics
{
public:
virtual ~IPhysics() {}
virtual void Move() = 0;
};
class IPhysicsFlight : public IPhysics
{
public:
virtual ~IPhysicsFlight() {}
virtual void Land() = 0;
virtual void TakeOff() = 0;
};
class Creature : public IGameObject, IPhysics
{
protected:
virtual void Move() {}
public:
Creature() {}
virtual ~Creature() {}
virtual void Update() {}
};
class CreatureAirborne : public Creature, IPhysicsFlight
{
private:
virtual void Land() {}
virtual void TakeOff() {}
public:
CreatureAirborne() {}
virtual ~CreatureAirborne() {}
virtual void Update();
};
void CreatureAirborne::Update()
{
TakeOff();
Creature::Move();
Land();
}
int main()
{
std::deque<std::shared_ptr<Creature>> creatures;
std::shared_ptr<Creature> cow(new Creature);
creatures.push_back(cow);
// The butterfly fails to compile with 'cannot instantiate; void IPhysics::Move(void) is abstract'
// std::shared_ptr<CreatureAirborne> butterfly(new CreatureAirborne);
// creatures.push_back(butterfly);
for (auto i : creatures)
{
i->Update();
}
}
It's somewhat had to follow your hierarchy, but it looks correct evaluation on the compiler's part.
You don't have virtual inheritance anywhere, so CreatureAirborne will have duplicated base classes from some point. You will have two instances of IPhysics. Move, that is abstract from there is implemented on the Creature branch but remains abstract on IPhysicsFlight.
You can cure the situation by using virtual inheritance somewhere, or by implementing Move in descendant (say just calling the parent version where it exists).
I would look at things little differently
class CreatureAirborne : public IPhysicsFlight,Creature
While the code runs
new CreatureAirborne ()
The compiler will try to build IPhysicsFlight base class and Creature base class and the fact that IPhysics is a base class to both doesn't play any role rather than confusing.As far as compiler is concerned IPhysicsFlight is abstract and CreatureAirborne did not implement Move
The diamond issue will actually come into play when you do a
(new CreatureAirborne ())->Move()
There probably is a fairly simple and straight-forward answer for this, but for some reason I can't see it.
I need to restrict calling methods from a class only to some methods implemented by derived classes of some interface.
Say I have
class A{
public:
static void foo();
};
class myInterface{
public:
virtual void onlyCallFooFromHere() = 0;
}
class myImplementation : public myInterface{
public:
virtual void onlyCallFooFromHere()
{
A::foo(); //this should work
}
void otherFoo()
{
A::foo(); //i want to get a compilation error here
}
}
So I should be able to call A::foo only from the method onlyCallFooFromHere()
Is there a way to achieve this? I'm open to any suggestions, including changing the class design.
EDIT:
So... I feel there's a need to further explain the issue. I have a utility class which interacts with a database (mainly updates records) - class A.
In my interface (which represents a basic database objects) I have the virtual function updateRecord() from which I call methods from the db utility class. I want to enforce updating the database only in the updateRecord() function of all extending classes and nowhere else. I don't believe this to be a bad design choice, even if not possible. However, if indeed not possible, I would appreciate a different solution.
Change the class design - what you want is impossible.
I am unsure of what you are trying to achieve with so little details and I am unable to comment further.
[Disclaimer: this solution will stop Murphy, not Macchiavelli.]
How about:
class DatabaseQueryInterface {
public:
~virtual DatabseQueryInterface() = 0;
virtual Query compileQuery() const = 0; // or whatever
virtual ResultSet runQuery(const Query&) const = 0; // etc
};
class DatabaseUpdateInterface : public DatabaseQueryInterface {
public:
virtual Update compileUpdate() const = 0; // whatever
};
class DatabaseObject {
public:
virtual ~DatabaseObject() = 0;
protected:
virtual void queryRecord(const DatabaseQueryInterface& interface) = 0;
virtual void updateRecord(const DatabaseUpdateInterface& interface) = 0;
};
class SomeConcreteDatabaseObject : public DatabaseObject {
protected:
virtual void updateRecord(const DatabaseUpdateInterface& interface) {
// gets to use interface->compileUpdate()
}
virtual void queryRecord(const DatabaseQueryInterface& interface) {
// only gets query methods, no updates
}
};
So the basic idea is that your DatabaseObject base class squirrels away a private Query object and a private Update object and when it comes time to call the protected members of the subclass it hands off the Update interface to the updateRecord() method, and the Query interface to the queryRecord() method.
That way the natural thing for the subclasses is to use the object they are passed to talk to the database. Of course they can always resort to dirty tricks to store away a passed-in Update object and try to use it later from a query method, but frankly if they go to such lengths, they're on their own.
You could split your project into different TUs:
// A.h
class A
{
public:
static void foo();
};
// My.h
class myInterface
{
public:
virtual void onlyCallFooFromHere() = 0;
}
class myImplementation : public myInterface
{
public:
virtual void onlyCallFooFromHere();
void otherFoo();
};
// My-with-A.cpp
#include "My.h"
#include "A.h"
void myImplementation::onlyCallFooFromHere() { /* use A */ }
// My-without-A.cpp
#include "My.h"
void myImplementation::otherFoo() { /* no A here */ }
You probably know this, but with inheritance, you can have public, protected, and private member access.
If a member is private in the base class, the derived cannot access it, while if that same member is protected, then the derived class can access it (while it still isn't public, so you're maintaining encapsulation).
There's no way to stop specific functions from being able to see whats available in their scope though (which is what you're asking), but you can design your base class so that the derived classes can only access specific elements of it.
This could be useful because class B could inherit from class A as protected (thus getting its protected members) while class C could inherit from the same class A as public (thus not getting access to its protected members). This will let you get some form of call availability difference at least -- between classes though, not between functions in the same class.
This could work.
class myInterface;
class A {
private:
friend class myInterface;
static void foo();
};
class myInterface {
public:
virtual void onlyCallFooFromHere() {callFoo();}
protected:
void callFoo() {A::foo();}
};
Though at this point I think I'd just make A::foo a static of myInterface. The concerns aren't really separate anymore.
class myInterface {
protected:
static void foo();
};
Is there a reason foo is in A?
There was an interesting problem in C++, but it was more about architecture.
There are many (10, 20, 40, etc) classes describing some characteristics (mix-in classes), for example:
struct Base { virtual ~Base() {} };
struct A : virtual public Base { int size; };
struct B : virtual public Base { float x, y; };
struct C : virtual public Base { bool some_bool_state; };
struct D : virtual public Base { string str; }
// ....
The primary module declares and exports a function (for simplicity just function declarations without classes):
// .h file
void operate(Base *pBase);
// .cpp file
void operate(Base *pBase)
{
// ....
}
Any other module can have code like this:
#include "mixing.h"
#include "primary.h"
class obj1_t : public A, public C, public D {};
class obj2_t : public B, public D {};
// ...
void Pass()
{
obj1_t obj1;
obj2_t obj2;
operate(&obj1);
operate(&obj2);
}
The question is how do you know what the real type of a given object in operate() is without using dynamic_cast and any type information in classes (constants, etc)? The operate() function is used with a big array of objects in small time periods and dynamic_cast is too slow for it and I don't want to include constants (enum obj_type { ... }) because this is not the OOP-way.
// module operate.cpp
void some_operate(Base *pBase)
{
processA(pBase);
processB(pBase);
}
void processA(A *pA)
{
}
void processB(B *pB)
{
}
I cannot directly pass a pBase to these functions. And it's impossible to have all possible combinations of classes, because I can add new classes just by including new header files.
One solution that came to mind, in the editor I can use a composite container:
struct CompositeObject
{
vector<Base *pBase> parts;
};
But the editor does not need time optimization and can use dynamic_cast for parts to determine the exact type. In operate() I cannot use this solution.
So, is it possible to avoid using a dynamic_cast and type information to solve this problem? Or maybe I should use another architecture?
The real problem here is about what you are trying to achieve.
Do you want something like:
void operate(A-B& ) { operateA(); operateB(); }
// OR
void operate(A-B& ) { operateAB(); }
That is, do you want to apply an operation on each subcomponent (independently), or do you wish to be able to apply operations depending on the combination of components (much harder).
I'll take the first approach here.
1. Virtual ?
class Base { public: virtual void operate() = 0; };
class A: virtual public Base { public virtual void operate() = 0; };
void A::operate() { ++size; } // yes, it's possible to define a pure virtual
class obj1_t: public A, public B
{
public:
virtual void operate() { A::operate(); B::operate(); }
};
Some more work, for sure. Notably I don't like the repetition much. But that's one call to the _vtable, so it should be one of the fastest solution!
2. Composite Pattern
That would probably be the more natural thing here.
Note that you can perfectly use a template version of the pattern in C++!
template <class T1, class T2, class T3>
class BaseT: public Base, private T1, private T2, private T3
{
public:
void operate() { T1::operate(); T2::operate(); T3::operate(); }
};
class obj1_t: public BaseT<A,B,C> {};
Advantages:
no more need to repeat yourself! write operate once and for all (baring variadic...)
only 1 virtual call, no more virtual inheritance, so even more efficient that before
A, B and C can be of arbitrary type, they should not inherit from Base at all
edit the operate method of A, B and C may be inlined now that it's not virtual
Disadvantage:
Some more work on the framework if you don't have access to variadic templates yet, but it's feasible within a couple dozen of lines.
First thing that comes to mind is asking what you really want to achieve... but then again the second thought is that you can use the visitor pattern. Runtime type information will implicitly be used to determine at what point in the hierarchy is the final overrider of the accept method, but you will not explicitly use that information (your code will not show any dynamic_cast, type_info, constants...)
Then again, my first thought comes back... since you are asking about the appropriateness of the architecture, what is it that you really want to achieve? --without knowledge of the problem you will only find generic answers as this one.
The usual object oriented way would be to have (pure) virtual functions in the base class that are called in operate() and that get overridden in the derived classes to execute code specific to that derived class.
Your problem is that you want to decide what to do based on more than one object's type. Virtual functions do this for one object (the one left of the . or ->) only. Doing so for more than one object is called multiple dispatch (for two objects it's also called double dispatch), and in C++ there's no built-in feature to deal with this.
Look at double dispatch, especially as done in the visitor pattern.