K
K
Ketchuuuup2021-06-27 21:11:44
OOP
Ketchuuuup, 2021-06-27 21:11:44

How to implement a downcast to a template?

There is a class Base :

class Base
{
  public:
    Base *pointer = nullptr;

    virtual void add(Base *element) = 0;
    virtual void print() const = 0;
};


And there is an Element class inherited from it :
template <typename T>
class Element : public Base
{
  public:
    Element(T value) : value(value) { }

    virtual void add(Base *element) override
    {
        
    }

    virtual void print() const override
    {
      std::cout << value << std::endl;
    }

  private:
    T value = 0;
};


And the main function :
int main()
{
  Base *s = new Element <short> (1);
  Base *i = new Element <int> (2);
  Base *ll = new Element <long long> (4);

  ll->add(s);
  ll->add(i);
  ll->print();

  delete s;
  delete i;
  delete ll;

  return 0;
}


What is the best way to implement the add method ? The add method is designed to add to the value value of the object on which the add method was called , the value value of the object passed to the method (the main function should display 7 on the console).

My implementation attempt:
#include <iostream>
#include <typeinfo>

class Base
{
  public:
    Base *pointer = nullptr;

    virtual void add(Base *element) = 0;
    virtual void print() const = 0;

    template <typename> friend class Element;

  private:
    virtual const std::type_info& getType() const = 0;
};

template <typename T>
class Element : public Base
{
  public:
    Element(T value) : value(value) { }

    virtual void add(Base *element) override
    {
      const std::type_info &type = element->getType();

      if (type == typeid(short))
      {
        value += dynamic_cast <Element <short> *> (element)->value;
      }
      else if (type == typeid(int))
      {
        value += dynamic_cast <Element <int> *> (element)->value;
      }
      else if (type == typeid(long long))
      {
        value += dynamic_cast <Element <long long> *> (element)->value;
      }
    }

    virtual void print() const override
    {
      std::cout << value << std::endl;
    }

    template <typename> friend class Element;

  private:
    T value = 0;

    virtual const std::type_info& getType() const override
    {
      return typeid(T);
    }
};


IMHO, a very bad solution to this issue, since in the future it will be necessary to implement the subtract, multiply, divide methods and there will be much more types: char, float, double and all sorts of unsigned ones.

Please advise on the best way to implement this method.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
V
Vladislav, 2021-06-30
@Ketchuup69

It seems you are looking for the Visitor pattern https://ru.m.wikipedia.org/wiki/Visitor_(pattern...

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question