vendredi 17 janvier 2020

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

Aucun commentaire:

Enregistrer un commentaire