lundi 26 novembre 2018

Factory for Templated Child Class

I am trying to work with class inhertiance, and factory methods.

The basic structure is that I have a base class Base, and a derived class Child.

The method ChildFactory allows one to choose different implementations of Child, that still provide the same interface.

All of my classes are templates, since there will be some parameters that can be floats or ints or whatever.

However, I'm having some trouble getting all of the templates to play nicely together. The errors I'm getting are around unknown template names

I have a MWE that should help you get an idea of what I'm talking about, if my explanation is a little off (constructive critism on that appreciated!)

├── child.h
├── child_impl.h
└── main.cpp

main.cpp
#include "child.h"
#include <iostream>

int main()
{
    mwe::Child<float> *child_0;
    mwe::Child<float> *child_1;
    mwe::ChildFactory<float> = child_factory;

    int input_param_1 = 5;
    child_0 = child_factory.get_child(1, input_param_1);
    child_1 = child_factory.get_child(2, input_param_1);
    std::cout << child_0->method1() << "\n";
    std::cout << child_1->method1() << "\n";
    return 0;
}

child.h

#ifndef CHILD_H
#define CHILD_H

#include "child_impl.h"
#include <stdexcept>
#include <iostream>

namespace mwe
{
template<typename T>
    class Base
    {
    public:
        Base(){};
        virtual int method1() = 0;
        virtual T method2() const = 0;

    };

template<typename T>
    class Child : public Base<T>
    {
        public:
            Child(int input_param_1)
                : Base<T>(),
                input_param_1(input_param_1){};

            virtual int method1() = 0;
            virtual T method2() const = 0;

            protected:
           int input_param_1;
     };

template<typename T>
    class ChildFactory
    {
    private:
      Child<T> * _child;
    public:
      Child<T> * get_child(int choice,
                       int input_param_1)
      {
      switch(choice)
        {
        case 1:
          _child = new Child_Imp_0<T>(input_param_1);
        case 2:
          _child = new Child_Imp_1<T>(input_param_1);

        default:
          throw std::invalid_argument("recieved in valid layer type");
        }
      return _child;
    }
};

};
#endif //CHILD_H

child_impl.h

#ifndef CHILD_IMPL_H
#define CHILD_IMPL_H

#include "child.h"

namespace mwe
{
    template<typename T>
    class Child_Imp_0 : public Child<T>
    {
    public:
    Child_Imp_0(int input_param_1)
: Child<T>(input_param_1),
    input_param_2(10 * input_param_1)
      {};

  int method1()
  {
    return 0;
  };

  T method2() const
  {
    return 0;
  };

protected:
  int input_param_2;
};

  template<typename T>
class Child_Imp_1 : public Child<T>
{
public:
Child_Imp_1(int input_param_1)
  : Child<T>(input_param_1),
    input_param_2(100 * input_param_1)
      {};

  int method1()
  {
    return 1;
  };

  T method2() const
  {
    return 0;
  };

protected:
  int input_param_2;
};
}
#endif //CHILD_IMPL_H

Any thought on how this might be made to work?

I have been searching around for related questions, but to no avail thus far. This question and this are related, as well as some other ones. However they seem to be dealing with other complexities that I'm having difficulty applying to my issue.

Alternatively, are there any alternative designs that would offer the same functionality?

Aucun commentaire:

Enregistrer un commentaire