Question

Compte tenu de l'exemple de code suivant:

class Room {
    Room() : switch(*this) { }
    Lamp lamp;
    Switch switch;
    void TurnOn() { lamp.TurnOn(); }
}

class Switch {
    Switch(Room& room) : room(room) { }
    Room& room;
    void TurnOn() { room.lamp.TurnOn(); }
}

Je crois comprendre que le deuxième TurnOn() implique un niveau supplémentaire d'indirection, car nous devons suivre la référence à room.Est-ce correct?Cette indirection supplémentaire sera-t-elle supprimée si l'appel peut être intégré (soit via une insertion explicite, soit via l'optimisation de l'ensemble du programme au niveau de l'éditeur de liens)?Ou, en d'autres termes, la fonction TurnOn de Switch pourrait-elle être accélérée en la remplaçant par:

class Room {
    Lamp lamp;
    Switch switch;
    Room() : switch(*this,lamp) { }
    void TurnOn() { lamp.TurnOn(); }
}

class Switch {
    Room& room;
    Lamp& lamp;
    Switch(Room& room,Lamp& lamp) : room(room),lamp(lamp) { }
    void TurnOn() { lamp.TurnOn(); }
}

Ou, plus généralement, si vous détenez une référence à un objet, y a-t-il un niveau d'indirection moins impliqué dans l'accès à ses membres directement via une référence plutôt que via la référence puis le membre?

Merci

Était-ce utile?

La solution

Cela pourrait être plus rapide (mais pas beaucoup). Cependant, les deux exemples sont incorrects dans la mesure où ils interrompent l'encapsulation et violent la loi de Demeter . Ils exigent que la classe Switch ou toute personne qui l'instancie ait accès à la fois au Room lui-même et au Lamp qu'il contient. Bien sûr, nous supposons également que chaque pièce a une lampe et qu'une lampe ne peut exister que dans une pièce ... ce qui signifie que si ces conditions changent, il y a deux classes à changer au lieu d'une seule.

Le premier exemple serait mieux écrit comme

class Room {
  public:
    Room() : sw(*this) { }
    void TurnOn() { lamp.TurnOn(); }
  private:
    Lamp lamp;
    Switch sw;
};

class Switch {
  public:
    Switch(Room& room) : room(room) { }
    void TurnOn() { room.TurnOn(); }
  private:
    Room& room;
};

car alors le Room est responsable de ce qui est activé. Cela pourrait être une lampe, une radio. Switch n'a plus à s'en soucier. Ce sera probablement plus lent, mais c'est plus facile à gérer.

Si vous voulez exiger ce Switch, activez uniquement un Lamp, alors

class Room {
  public:
    Room() : sw(lamp) { }
    void TurnOn() { lamp.TurnOn(); } // (semantics: who "turns on" a room?)
  private:
    Lamp lamp;
    Switch sw;
};

class Switch {
  public:
    Switch(Lamp& lamp) : lamp(lamp) { }
    void TurnOn() { lamp.TurnOn(); }
  private:
    Lamp& lamp;
};

Cela devrait être tout aussi rapide, sans exiger que nous interrompions l'encapsulation.

Autres conseils

Votre deuxième exemple ne sera (probablement) pas plus rapide que le premier exemple.Dans les deux cas, une référence doit être résolue avant que TurnOn() puisse être invoqué.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top