2017-06-16 1 views
0

J'ai du mal à visualiser clairement mon idée avec des mots. L'exemple ci-dessous peut expliquer ma pensée. J'ai deux classes abstraites et deux classes dérivées,Toutes les classes abstraites en connaissent d'autres

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

=> et

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(); } 
}; 

=> les classes sont appelées

int main(){ 
Derived1 d1; 
Derived2 d2; 

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

Comment puis-je obtenir le **should call like** sans passer l'instance Base2 dans d1.update().

Une autre question est, comment ça s'appelle, quand chaque objet de classe connaît d'autres objets?

Merci.

+0

'Derived1' a besoin de la visibilité d'une instance de' Derived2'. En supposant que cette instance est représentée par une variable (ou un membre de données) nommée 'thing', elle peut faire' thing.update_data (* this) '. Cela dépend évidemment de la définition de la classe 'Derived2' visible par le compilateur au point d'appel (et lors de la création de' thing') – Peter

+1

Comment voulez-vous que Derived1 :: update() sache quelle instance d'un objet Derived2 appelle update_data () dans ce scénario? –

+0

Vous devriez probablement lire à propos des différences entre la classe et l'objet (ou l'instance de la classe). Cela vous aidera à comprendre comment réaliser ce que vous voulez. Je vous ai également recommandé de lire sur le modèle d'observateur, car c'est probablement ce que vous voulez réaliser. – Logman

Répondre

0

Il semble que vous ayez besoin d'une technique appelée double-dispatch. C++ prend uniquement en charge le dispatch unique - le comportement que vous obtenez est basé uniquement sur une instance unique.

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

Pour l'expédition double, (qui n'existe pas), vous auriez besoin de quelque chose comme

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

Il y a des solutions au problème. Ceux-ci exigent un travail où un type exige la connaissance de l'autre, mais seulement de cette façon. Considérons un ensemble de formes géométriques que nous voulons dessiner sur des surfaces. classe 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 { 
    }; 

Le code que nous voulons réellement appeler dépend de la surface et de la forme. Pour résoudre ce problème, nous choisissons l'une des hiérarchies les plus bornées et indiquons à l'autre hiérarchie les instances concrètes du type.

Dans cet exemple, il est considéré que plus de formes et d'objets pouvant être dessinés existeront que des technologies pour les rendre.

Ainsi, chaque article tirable saura dessiner sur chacune des 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); 
     } 

    }; 

maintenant un appel à Surface->draw(Drawable *) sera rebondi dans une mise en œuvre concrète, où chaque Drawable comprend comment rendre sur un appareil, mais les appareils ont aucune connaissance de la gamme des Drawable s

Pour aller plus loin : wikipedia : double dispatch pour une description plus complète.

et je recommande le design patterns livre wikipedia : design patterns

Les modèles de conception donnent une idée d'un vocabulaire de conception qui rendent cette demande sous forme de question beaucoup plus facile.