Using abstract class in C++ for dependency injection - c++

With the reference of this Stackoverflow question, I'm not able to figure out the same problem of implementing DI using interface in c++ style, i.e. abstract class. Instead of bumping up old thread I created this one. Compiler throws error for the last line.
class IService {
virtual void DoWork() = 0;
virtual bool IsRunning() = 0;
};
class ClientA : IService {
void DoWork() {
std::cout << "Work in progress inside A";
}
bool IsRunning() {
return true;
}
};
class ClientB : IService {
void DoWork() {
std::cout << "Work in progress inside B";
}
bool IsRunning() {
return true;
}
};
class Server {
IService* _service;
Server(IService* service) : _service(service)
{ }
// Error: this declaration has no storage class or type specifier
// Compiler: MSVC 2017
_service->DoWork();
};

In C++ class members are private by default.
You should specify public: before virtual void DoWork() = 0;.
C++ inheritance is private by default (when using class keyword). Instead of : IService, try : public IService. See differences between private, protected, public inheritance here.
Where is the function body of _service->DoWork();?

I believe this is what you wanted:
#include <iostream>
using namespace std;
struct IService {
virtual ~IService() = default; // Remember about virtual dtor to avoid memory leaks!
virtual void DoWork() = 0;
virtual bool IsRunning() = 0;
};
class ClientA : public IService {
void DoWork() {
std::cout << "Work in progress inside A" << endl;
}
bool IsRunning() {
return true;
}
};
class ClientB : public IService {
void DoWork() {
std::cout << "Work in progress inside B" << endl;
}
bool IsRunning() {
return true;
}
};
class Server {
IService* _service;
public:
Server(IService* service) : _service(service)
{ }
void doStuff() {
_service->DoWork();
}
};
int main() {
ClientA a;
ClientB b;
Server sa(&a), sb(&b);
cout << "ServerA: " << endl;
sa.doStuff();
cout << "ServerB: " << endl;
sb.doStuff();
return 0;
}
Ideone
You need to get yourself familiar with the concept of access specifiers in C++. See here

Related

How to override two methods of 2 parents that inherits same classes with virtual methods in C++

Consider the next Example:
#include <iostream>
class Base{
public:
virtual void f() {
std::cout << "Base::f()" << std::endl;
}
};
class Derived1 : public Base
{
public:
virtual void f() override
{
Base::f();
std::cout << "Derived1::f()" << std::endl;
}
};
class Derived2 : public Base
{
public:
virtual void f() override
{
Base::f();
std::cout << "Derived2::f()" << std::endl;
}
};
class DerivedUnion : public Derived1, public Derived2
{
public:
void Derived1::f() override { // Errors
}
void Derived2::f() override { // Errors
}
};
is there some how that allow me to override the
Derived2::f()
in the
DerivedUnion{}
class?
I have tried to target specific one with namespace like style, but it didnt worked:
class DerivedUnion : public Derived1, public Derived2
// Notice DerivedUnion is not a Union, name is for
// Demostration Purposes, not intended to create
// A union Behavior
{
public:
virtual void Derived1::f() override; // Compile error
virtual void Derived2::f() override; // Compile error
virtual void f() override; // Not a compile error, but both Derived1 and Derived2 call same
};
void UseBase(Base* b){
b->f(); // expected Ambiguos call compile time
b->DerivedUnion::f() // Expected overriden DerivedUnion::f() to be called
b->Derived1::f(); // Expected overriden Derived1::f() to be called
b->Derived2::f(); // Expected overriden Derived2::f() to be called
}
An Example of it could be this one, code is self explanatory:
#include <iostream>
/* Interface Drawable */
class IDrawable {
public:
virtual void Draw() {};
};
/* Asume this is a button from one kind of bar */
class ButtonA : public IDrawable{
public:
virtual void Draw() override {
std::cout << "ButtonA::Draw()" << std::endl;
}
};
/* Asume this is a button from another kind of bar */
class ButtonB : public IDrawable{
public:
virtual void Draw() override {
std::cout << "ButtonB::Draw()" << std::endl;
}
};
/**
Where Component X is a representation that will represent 2 buttons types
*/
class ComponentX : public ButtonA, public ButtonB {
public:
void ButtonA::Draw() override { // cannot define member function ‘ButtonA::Draw’ within ‘ComponentX’
ButtonA::Draw();
std::cout << "Custom ComponentX::Draw()" << std::endl;
}
void ButtonB::Draw() override { // error: cannot define member function ‘ButtonB::Draw’ within ‘ComponentX’
ButtonB::Draw();
std::cout << "Custom ComponentX::Draw()" << std::endl;
}
};
class ComponentY : public ButtonA, public ButtonB {
public:
void ButtonA::Draw() override { // cannot define member function ‘ButtonA::Draw’ within ‘ComponentY’
ButtonA::Draw();
std::cout << "Custom ComponentY::Draw()" << std::endl;
}
void ButtonB::Draw() override { // error: cannot define member function ‘ButtonB::Draw’ within ‘ComponentY’
ButtonB::Draw();
std::cout << "Custom ComponentY::Draw()" << std::endl;
}
};
using namespace std;
void DummyAddButtonA(ButtonA* pBtnA)
{
//Add it somewhere ...
}
void DummyAddButtonB(ButtonB* pBtnB)
{
//Add it somewhere ...
}
int main()
{
ComponentX compx;
ComponentY compy;
DummyAddButtonA(&compx);
DummyAddButtonB(&compx);
DummyAddButtonA(&compy);
DummyAddButtonB(&compy);
return 0;
}

How to use multiple inheritance for implementing different comparison logic?

I am trying to use interface IComparable (not in this mockup code) and its 2 implementations to work on same object.
I must use operators to do so.
I would like to do it without resolving like here c.right::operator--().
Here I have interfaces Common and Uni both inherited by Inter. Then I have right and left that blend into custom class implementing both Common and 2 versions of Uni interfaces.
2 different versions meaning one that uses operator to call f() and the other to call g().
#include<iostream>
class Common {
public:
Common() { std::cout << "common\n"; }
};
class Uni {
public:
Uni() { std::cout << "uni\n"; }
virtual void operator--() = 0;
};
class Inter : virtual public Common, public Uni {
public:
Inter() { std::cout << "inter\n"; }
};
class left : public Inter {
public:
left() { std::cout << "left\n"; }
void operator--() override { f(); }
virtual void f() = 0;
};
class right : public Inter {
public:
right() { std::cout << "right\n"; }
void operator--() override { g(); }
virtual void g() = 0;
};
class custom : public right, public left {
public:
custom() { std::cout << "custom\n"; }
void f() override { std::cout << "lol\n"; }
void g() override { std::cout << "gfunc\n"; }
};
class custom2 : public right, public left {
public:
custom2() { std::cout << "custom2\n"; }
void f() override { std::cout << "lol2\n"; }
void g() override { std::cout << "gfunc2\n"; }
};
int main()
{
custom c;
custom2 c2;
c.left::operator--();
c.right::operator--();
c2.right::operator--();
}

C++ Polymorphism and templated interfaces

I'm familiar with polymorphism in general, but I'm fairly new to C++ in general and templates in particular. I have to following situation with a mixture of code that I cannot change (usage of a framework, all events and templated event listeners) and code under my control (clients in the example below).
#include <string>
#include <iostream>
#include <vector>
class EventBase {
public:
virtual std::string getData() const = 0;
};
class EventA : public EventBase {
public:
std::string getData() const override {
return "Event A";
}
};
class EventB : public EventBase {
public:
std::string getData() const override {
return "Event B";
}
};
template<class T_Event>
class IEventHandler
{
public:
virtual void onEvent(const T_Event& e) = 0;
virtual void onError() = 0;
};
class ClientBase {
public:
virtual void startReceiving() = 0;
virtual void stopReceiving() {
std::cout << "ClientBase::stopReceiving" << std::endl;
}
};
class ClientA : public ClientBase, public IEventHandler<EventA> {
public:
void onEvent(const EventA& e) override {
std::cout << "ClientA::onEvent - e.getData()= " << e.getData() << std::endl;
};
void onError() override {
std::cout << "ClientA::onError" << std::endl;
};
void startReceiving() override {
std::cout << "ClientA::startReceiving" << std::endl;
};
};
class ClientB : public ClientBase, public IEventHandler<EventB> {
public:
void onEvent(const EventB& e) override {
std::cout << "ClientB::onEvent - e.getData()= " << e.getData() << std::endl;
};
void onError() override {
std::cout << "ClientB::onError" << std::endl;
};
void startReceiving() override {
std::cout << "ClientB::startReceiving" << std::endl;
};
};
int main(int, char**) {
//User Code
ClientA ca;
ClientB cb;
std::vector<ClientBase*> baseClients;
baseClients.push_back(&ca);
baseClients.push_back(&cb);
for(const auto client : baseClients){
client->startReceiving();
}
//Framework Code
EventA a;
EventB b;
std::vector<IEventHandler<EventA>*> eventHandlersA;
std::vector<IEventHandler<EventB>*> eventHandlersB;
eventHandlersA.push_back(&ca);
eventHandlersA[0]->onError();
eventHandlersA[0]->onEvent(a);
eventHandlersB.push_back(&cb);
eventHandlersB[0]->onError();
eventHandlersB[0]->onEvent(b);
//User Code
for(const auto client : baseClients){
client->stopReceiving();
}
}
See here: https://onlinegdb.com/2MYQhC2G5
What I want to do now is to have a common default implementation of onError.
To do so, I tried at least four approaches. Only the second worked. It would be nice to hear from C++ savants if this approach 2 is actually the way to do it.
Approach 1
Simply put onError in ClientBase and remove it from derived clients.
class ClientBase {
public:
virtual void startReceiving() = 0;
virtual void stopReceiving() {
std::cout << "ClientBase::stopReceiving" << std::endl;
}
virtual void onError(){
std::cout << "ClientBase::onError" << std::endl;
}
};
class ClientA : public ClientBase, public IEventHandler<EventA> {
public:
void onEvent(const EventA& e) override {
std::cout << "ClientA::onEvent - e.getData()= " << e.getData() << std::endl;
};
void startReceiving() override {
std::cout << "ClientA::startReceiving" << std::endl;
};
};
Fails on compile time with
error: variable type 'ClientA' is an abstract class
note: unimplemented pure virtual method 'onError' in 'ClientA'
Okay, it's abstract since it does not implement the methods needed from IEventHandler<EventA>
Approach 2
Fix the unimplemented method in ClientA but call the super class method implementation:
class ClientA : public ClientBase, public IEventHandler<EventA> {
public:
void onEvent(const EventA& e) override {
std::cout << "ClientA::onEvent - e.getData()= " << e.getData() << std::endl;
};
void onError() override {
ClientBase::onError();
};
void startReceiving() override {
std::cout << "ClientA::startReceiving" << std::endl;
};
};
Works, though under the hood I think other things are happening then originally intended (might be more of a delegation then inheritance).
Maybe mess around with templates?
Approach 3: Remove the IEventHandler from the derived clients
class ClientBase : public IEventHandler<EventBase> {
public:
virtual void startReceiving() = 0;
virtual void stopReceiving() {
std::cout << "ClientBase::stopReceiving" << std::endl;
}
virtual void onError(){
std::cout << "ClientBase::onError" << std::endl;
}
virtual void onEvent(const EventBase& e) = 0;
};
class ClientA : public ClientBase {
public:
void onEvent(const EventA& e) override {
std::cout << "ClientA::onEvent - e.getData()= " << e.getData() << std::endl;
};
void startReceiving() override {
std::cout << "ClientA::startReceiving" << std::endl;
};
};
Build system hates me:
error: non-virtual member function marked 'override' hides virtual member function
note: hidden overloaded virtual function 'ClientBase::onEvent' declared here: type mismatch at 1st parameter ('const EventBase &' vs 'const EventA &')
error: variable type 'ClientA' is an abstract class
note: unimplemented pure virtual method 'onEvent' in 'ClientA' - virtual void onEvent(const EventBase& e) = 0;
Okay, so you can override methods only if the signature matches exactly.
Approach 4: Make ClientBase templated
template<class T_Event>
class ClientBase {
public:
virtual void startReceiving() = 0;
virtual void stopReceiving() {
std::cout << "ClientBase::stopReceiving" << std::endl;
}
virtual void onError(){
std::cout << "ClientBase::onError" << std::endl;
}
virtual void onEvent(const T_Event& e) = 0;
};
class ClientA : public ClientBase<EventA> {
public:
void onEvent(const EventA& e) override {
std::cout << "ClientA::onEvent - e.getData()= " << e.getData() << std::endl;
};
void startReceiving() override {
std::cout << "ClientA::startReceiving" << std::endl;
};
};
Again, no success. This time my structures to track my clients would break:
std::vector<ClientBase*> baseClients; ----> error: use of class template 'ClientBase' requires template arguments
eventHandlersA.push_back(&ca); ---> error: no matching member function for call to 'push_back'
Do you have any more ideas on how to achieve the original goal? Or is sticking to approach 2 a good solution?
Your insights into approaches 1-3 are generally correct:
Approach 1 failed because ClientBase didn't inherit from IEventHandler<> which declared the virtual method.
Approach 2 is indeed a delegation, which is fine in my opinion. Virtual methods are already a delegation - under the hood a vtable is roughly equivalent to a set of function pointers. Delegating onError is just one more level of indirection, and hopefully something called onError isn't called frequently enough to make the performance penalty significant.
Approach 3 failed because anything overriding onEvent(const EventBase& e) needs to accept any EventBase&, per the contract.
Approach 4 failed because ClientBase<EventA> and ClientBase<EventB> are completely different types that don't share a common base. Templates are more like type factories than types - there's no relationship between instantiations.
If you want to make the this work with inheritance, you can spell out that common base explicitly by having a non-template ClientBase and a template layer in between to implement onError:
template <typename TEvent>
class ErrorHandlingClient : public ClientBase, public IEventHandler<TEvent> {
public:
virtual void onError() override { /* ... */ }
};
class ClientA : public ErrorHandlingClient<EventA> {
public:
void onEvent(const EventA& e) override { /* ... */ }
void startReceiving() override { /* ... */ }
};
class ClientB : public ErrorHandlingClient<EventB> {
public:
void onEvent(const EventB& e) override { /* ... */ }
void startReceiving() override { /* ... */ }
};
ClientA and ClientB will have different implemenations of onError because of the template, but they can both be casted to a common ClientBase type to store in a vector.
One last opinion - if you need an abstract class to get your desired code organization, it might be a sign that your concerns aren't separated: Maybe IEventHandler<T> should really be two interfaces, or maybe error handling should be owned by some other entity.
The basic problem is having a class template with a virtual method that does not need the template parameter. It is not wrong per se, but it can easily make one's life mighty inconvenient.
The problem with your Approach 1 is having more than one source node in the inheritance graph that has errorHandler. These functions are unrelated. Here is a simplified demo:
struct X { virtual void foo() = 0; };
struct Y { virtual void foo() {} };
struct XY : X, Y {};
XY is still abstract, despite having an implementation of foo, because there are two unrelated foos in it and the only way to unify them is to override foo in XY. This surprises a lot of people.
The best practice here (as I understand it) is moving the offending function to a common base class of X, Y and XY (create one if needed). Up the hierarchy, not down or sideways. It should be inherited virtually (not a diamond-of-death problem, since it is an ABC with no data members).
So don't do this:
template<class T_Event>
class IEventHandler
{
public:
virtual void onEvent(const T_Event& e) = 0;
virtual void onError() = 0;
};
Do this instead:
class IErrorHandler {
public:
virtual void onError() = 0;
// or whatever default implementation you want
};
template<class T_Event>
class IEventHandler : public virtual /* XXX Important! */ IErrorHandler
{
public:
virtual void onEvent(const T_Event& e) = 0;
};
class ClientBase : public virtual IErrorHandler {
virtual void onError() override {} // whatever
};
class ClientA : public ClientBase, public IEventHandler<EventA> {
virtual void onEvent(const EventA& e) {}
};
Live Demo.
Note, the MSVC compiler may issue a warning (C4250) on this. Ignore or silence it. For your convenience, here is a collection of SO posts on this topic.

Best implementation for a class that can have different base member implementations

I would like to have a child class Handler that handles multiple callbacks and transfers data from one class to another. However, the base classes B1 and B2can have different implementations for its members.
Below a way to implement the behavior I want. I think there should be a better way but cannot figure it out.
// Example program
#include <iostream>
#include <string>
template <class T>
class IBase
{
public:
IBase()
{
object = new T(*this);
};
~IBase()
{
delete object;
}
virtual void ValidateCallback()
{
};
void RxCallback()
{
object->RxCallback();
};
void Send()
{
object->Send();
};
T* object;
};
class C1
{
public:
virtual void RxCompleteCallback() = 0;
void RxParse()
{
std::cout << "Parse C1" << std::endl;
RxCompleteCallback();
};
};
class C2
{
public:
virtual void RxCompleteCallback() = 0;
void RxParse()
{
std::cout << "Parse C2" << std::endl;
RxCompleteCallback();
};
};
class B1 : public C1
{
public:
B1(IBase<B1> &handler )
{
ihandler = &handler;
};
void DoSomething()
{
std::cout << "DoSomething B1" << std::endl;
ihandler->ValidateCallback();
};
void RxCompleteCallback() override
{
std::cout << "DoSomething other than B2" << std::endl;
std::cout << "RxCompleteCallback" << std::endl;
};
void RxCallback()
{
RxParse();
};
void Send()
{
DoSomething();
};
IBase<B1> * ihandler;
};
class B2 : public C2
{
public:
B2(IBase<B2> &handler )
{
ihandler = &handler;
};
void DoSomething()
{
std::cout << "DoSomething B2" << std::endl;
ihandler->ValidateCallback();
};
void RxCompleteCallback() override
{
std::cout << "DoSomething other than B1" << std::endl;
std::cout << "RxCompleteCallback" << std::endl;
};
void RxCallback()
{
RxParse();
};
void Send()
{
DoSomething();
};
IBase<B2> * ihandler;
};
class Validate
{
public:
void CalculateValidation()
{
std::cout << "Calculate validation" << std::endl;
};
};
template <class T>
class Handler : public IBase<T>, public Validate
{
public:
void ValidateCallback() override
{
std::cout << "ValidateCallback" << std::endl;
CalculateValidation();
};
void Receive()
{
IBase<T>::RxCallback();
};
void Send()
{
IBase<T>::Send();
}
};
int main()
{
Handler<B1> handler1;
handler1.Receive();
handler1.Send();
std::cout << std::endl;
Handler<B2> handler2;
handler2.Receive();
handler2.Send();
}
Output:
Parse C1
DoSomething other than B2
RxCompleteCallback
DoSomething B1
ValidateCallback
Calculate validation
Parse C2
DoSomething other than B1
RxCompleteCallback
DoSomething B2
ValidateCallback
Calculate validation
There are several ways to do this in C++. It's hard to say what the best way is, it depends on how you will use it, and the example you gave is too simple to recommend a specific way. Normally, I'd say you want to derive your protocol-specific classes from Handler, instead of the other way around, so you'd write:
class Handler {
public:
virtual void Receive() {};
virtual void Send() {};
};
class B1: public Handler {
virtual void Receive() {
...
}
virtual void Send() {
...
}
};
int main() {
B1 handler1;
handler1.Receive();
...
}
The main issue here is that you need to use virtual member functions here, otherwise the base class doesn't know which derived class's implementation to call. But it does allow you to pass a Handler * as an argument to another function, which will then work with any derived class without needing any templating.
Another option is to use the curiously recurring template pattern, which would look like:
template <typename T>
class Handler {
void Receive() {
static_cast<T*>(this)->Receive();
}
void Send() {
static_cast<T*>(this)->Send();
}
};
class B1: public Handler<B1>
{
void Receive() {
...
}
void Send() {
...
}
};
int main() {
B1 handler1;
handler1.Receive();
...
}
This avoids virtual methods.
It is also quite similar to your class Handler, but it has the advantage that it doesn't need the T *object member variable.

Decorator pattern vs. Call super anti-pattern

Let's have a simple Decorator example:
struct IStuff {
virtual void Info()=0;
virtual ~IStuff() { }
};
class Ugly : public IStuff {
public:
void Info() { cout << "Ugly"; }
};
class Shiny : public IStuff {
IStuff* stuff;
public:
Shiny(IStuff* stuff) {
this->stuff = stuff;
}
~Shiny() {
delete stuff;
}
void Info() {
stuff->Info(); // <------------------------------- call super?
cout << "->Shiny";
}
};
int main() {
IStuff* s = new Ugly();
s = new Shiny(s); // decorate
s = new Shiny(s); // decorate more
s->Info(); // Ugly->Shiny->Shiny
delete s;
return 0;
}
Is this also the Call super anti-pattern?
Call super is a design pattern in which a particular class stipulates that in a derived subclass, the user is required to override a method and call back the overridden function itself at a particular point.
Here is a little different implementation Is there any difference in design?
This is not Call super. You call the Info method of another IStuff instance, not the overriden version.
Call super version:
struct IStuff {
// If you override this, you MUST call the base class version <-- call super
virtual void Info()
{
// a default implementation.
std::cout << "Super call ";
}
virtual ~IStuff() { }
};
class Shiny : public IStuff {
public:
void Info() {
IStuff::Info(); // don't forget to call base implementation.
std::cout << "->Shiny";
}
};
Some implementations of Decorator are making a super call to a Decorator base class, that is responsible to hold, call and manage the decorated reference:
struct IStuff
{
virtual void Info() = 0;
virtual ~IStuff() { }
};
class Stuff : public IStuff
{
public:
void Info() { std::cout << "Basic stuff"; }
};
class StuffDecorator : public IStuff
{
IStuff* decorated_;
public:
StuffDecorator(IStuff* decoratedStuff) :
decorated_(decoratedStuff) {}
~StuffDecorator() { delete decorated_; }
void Info()
{
decorated_->Info();
}
};
class Shiny : public StuffDecorator
{
public:
Shiny(IStuff* stuff) : StuffDecorator(stuff) { }
void Info()
{
StuffDecorator::Info();
std::cout << "->Shiny";
}
};
To avoid the super call you might want to combine Decorator with Template Method:
class StuffDecorator : public IStuff
{
IStuff* decorated_;
public:
StuffDecorator(IStuff* decoratedStuff) :
decorated_(decoratedStuff) {}
~StuffDecorator() { delete decorated_; }
void Info()
{
decorated_->Info();
DoInfo();
}
private:
// Template method
virtual void DoInfo() = 0;
};
class Shiny : public StuffDecorator
{
public:
Shiny(IStuff* stuff) : StuffDecorator(stuff) { }
private:
void DoInfo()
{
std::cout << "->Shiny";
}
};