0

I'm having trouble to clearly visualize my idea in words. Below example may explain my thinking. I've two abstract class and two Derived class,

class Base1{
        public:
        virtual void f1() = 0;
        std::string get(){ return "HelloWorld";}
};

class Derived1: public Base1{
        public:
        void f1() {}
        void update (std::string& update){
            **should call like**  Base2::Derived2::update_data(this);}
};

=> and

class Base2{
        public:
        virtual void f2 () = 0;
};

class Derived2: public Base2{
        public:
        void f2() {}
        void get (Base1& d1){ d1.Base1::get (); }
        void update_data (Base1& d1){ d1.Base1::get (); }
};

=> the classes are called as

int main(){
Derived1 d1;  
Derived2 d2;  

d2.get (d1);  
std::string hi = "hiWorld";
d1.update (hi);
return 0;
}

How can I achieve the **should call like** without passing the Base2 instance in d1.update ().

Another question is, what does it called, when each class objects knows other objects?

Thanks.

meAbab
  • 102
  • 9
  • `Derived1` needs visibility of an instance of `Derived2`. Assuming that instance is represented by a variable (or data member) named `thing`, it can do `thing.update_data(*this)`. That obviously relies on the definition of class `Derived2` being visible to the compiler at the call point (and when creating `thing`) – Peter Jun 16 '17 at 23:57
  • 1
    How would you expect Derived1::update() know which instance of a Derived2 object to call update_data() on, in this scenario? – Jeremy Friesner Jun 17 '17 at 00:07
  • You probably should read about differences between class and object (or instance of class). It will help you understand how to achieved what you want. I also recommended you to read about observer pattern as it's probably what you want to achieve. – Logman Jun 17 '17 at 00:36

1 Answers1

0

It seems like you need a technique called double-dispatch. C++ only directly supports single-dispatch - the behavior you get is only based on a single instance.

   a->virtualFunction( params );  // exactly which implementation is called depends on the concrete type of a.

For double dispatch, (which does not exist), you would need something like

  (a,b)->virtualFunction( params );  // where the call is based on both parameters.

There are some solutions to the problem. These require work where one type requires the knowledge of the other, but only that way round.

Consider a set of geometric shapes which we want to draw on surfaces. class Surface; class Drawable { public: virtual ~Drawable () {} virtual void draw( Surface * ) = 0; };

   class Surface {
     public:
        virtual ~Surface () {}
   // details ommitted.
   }

   class Rectangle : public Drawable {
   };
   class Circle : public Drawable {
   }

   // and some surfaces

   class PrinterSurface : public Surface {
   };

   class PlotterSurface : public Surface {
   };

The code we actually want to call, is dependent on both the surface and the shape.

To solve this, we choose one of the hierarchies which is most bounded, and tell the other hierarchy about the concrete instances of the type.

In this example, it is considered that more shapes and drawable objects will exist than technologies for rendering them.

So each drawable item will know how to draw on each of the surfaces.

   class Drawable {
     public:
        virtual ~Drawable () {}
        virtual void drawPrinter( Surface * ) = 0;
        virtual void drawPlotter( Surface * ) = 0;
        virtual void drawSurface( Surface * ) = 0;
   };

   class Surface {
     public:
        virtual ~Surface () {}
        virtual void draw( Drawable * pDrawable ) = 0;
   }

   class PrinterSurface : public Surface { 
      void draw( Drawable * pDrawable ) {
           pDrawable->drawPrinter( this );
      }

   };

Now a call to Surface->draw( Drawable *) will be bounced into a concrete implementation, where each Drawable understands how to render onto a device, but the devices have no knowledge of the gamut of Drawables

For further reading : wikipedia : double dispatch for a more full description.

and I would recommend the design patterns book wikipedia : design patterns

The design patterns give some idea of a vocabulary of design which make asking this form of question much easier.

mksteve
  • 12,614
  • 3
  • 28
  • 50