1

The problem is: ExampleIt which inherits (and overrides methods) from class It, so that when I overload operator in class Wrapped (which calls some methods from It, which should be overridden by ExampleIt.

The wanted effect is that when I overload operator* I should be able to call *name_of_Wrapped_class and this should execute virtual method dereference (from It) which should be overridden by 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()
};
einpoklum
  • 118,144
  • 57
  • 340
  • 684
  • Does your object derive from both `Wrapped` *and* `ExampleIt`? Otherwise, I'm not sure what you are asking. Perhaps you meant to make `Wrapped` inherit from `ExampleIt`? – François Andrieux Apr 27 '18 at 20:01
  • Do you mean that `Wrapped` should hold a pointer or reference to `It` which could refer to any class derived from `It`.? – quamrana Apr 27 '18 at 20:03
  • Are just trying to create a shim helper function that calls on the virtual function? You can just declare such functions in your interface base class. – Gem Taylor Apr 27 '18 at 20:04
  • There is no relationship between `Wrapped` and `ExampleIt` (other than they happen to both derive from `It`). Member functions of either are not member functions of the other. – Peter Apr 27 '18 at 23:08

2 Answers2

1

Before actually answering, I have to say your class hierarchy and naming seem kind of fishy. Your dereferencing operator returns a value rather than a reference - which is not how dereferencing works on plain pointers.

Still, you asked for it, so here you go. Two options to implement your operator*() overloading (each with its pros and cons which I won't go into here):

  1. Run-time polymorphic behavior, using a pointer:

    class Wrapped {
    protected:
        It* it;
    public:
        std::pair<int, std::string> operator*() const {
            return it->dereference();
        };
    };
    
  2. Compile-time polymorphism using the Curiously Recurring Template Pattern (CRTP):

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

    with this option, you don't even need It and ExampleIt to be related; any class with a dereference() method will do.

einpoklum
  • 118,144
  • 57
  • 340
  • 684
0

Here is the sample code, which I think shows what you want,

      #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;
      }

Note the member it was assigned during the construction with type ExampleIt.

CS Pei
  • 10,869
  • 1
  • 27
  • 46