Множественное, но уникальное наследование классов - PullRequest
0 голосов
/ 27 апреля 2018

Проблема в том, что ExampleIt наследует (и переопределяет методы) из класса It, поэтому при перегрузке оператора в классе Wrapped (который вызывает некоторые методы из It, который должен быть переопределен ExampleIt.

Требуемый эффект заключается в том, что при перегрузке operator* я должен иметь возможность вызвать *name_of_Wrapped_class, и это должно выполнить виртуальный метод dereference (из It), который должен быть переопределен на ExampleIt.

class It {
public:
    virtual std::pair<int, std::string> dereference() const;
};

class ExampleIt : It {
public:
    std::pair<int, std::string> dereference() const override;
};

class Wrapped : It{ //??? not sure about that
public:
     std::pair<int, std::string> operator*() const; // it should call for dereference()
};

Ответы [ 2 ]

0 голосов
/ 27 апреля 2018

Вот пример кода, который, я думаю, показывает, что вы хотите,

      #include <iostream>

      using namespace std;

      class It {
      public:
          virtual std::pair<int, std::string> dereference() const{
              std::cout << "it\n";
              return make_pair(3, "");
          }
      };

      class ExampleIt : public It {
      public:
        std::pair<int, std::string> dereference() const override{
              std::cout << "example it\n";
              return make_pair(2, "");
          }
      };

      class Wrapped {
          It * it;
      public:
          Wrapped() : it (new ExampleIt()) {}
           std::pair<int, std::string> operator*() const{
              std::cout << "Wrapped it\n";
              it->dereference();
              return make_pair(1, "");
           }
      };

      int main() {
          Wrapped p;
          auto x = *p;
          std::cout << x.first << std::endl;
      }

Обратите внимание, что член it был назначен во время построения с типом ExampleIt.

0 голосов
/ 27 апреля 2018

Прежде чем ответить на самом деле, я должен сказать, что ваша иерархия классов и наименование кажутся немного странными. Ваш оператор разыменования возвращает значение, а не ссылку - это не то, как разыменование работает на простых указателях.

Тем не менее, вы просили об этом, так что вот и все. Два варианта реализации вашей operator*() перегрузки (каждый со своими плюсами и минусами, которые я не буду здесь рассматривать):

  1. Полиморфное поведение во время выполнения с использованием указателя:

    class Wrapped {
    protected:
        It* it;
    public:
        std::pair<int, std::string> operator*() const {
            return it->dereference();
        };
    };
    
  2. полиморфизм во время компиляции с использованием любопытно повторяющегося шаблона (CRTP) :

    template <typename Base>
    class Wrapped: Base {
    public:
        std::pair<int, std::string> operator*() const {
            return Base::dereference();
        };
    };
    

    с этой опцией вам даже не нужно, чтобы It и ExampleIt были связаны; подойдет любой класс с методом dereference().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...