0

次のコード例を考えます。

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

ここでの私の理解では、TurnOn()部屋への参照に従う必要があるため、2 番目の方法には余分なレベルの間接性が含まれます。これは正しいです?呼び出しをインライン化できる場合 (明示的なインライン化またはリンカー レベルでのプログラム全体の最適化のいずれか)、その余分な間接化は削除されますか? または、別の言い方をすれば、Switch の TurnOn 機能を次のように変更することで高速化できます。

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

または、より一般的には、オブジェクトへの参照を保持している場合、参照を介してメンバーに直接アクセスするのではなく、参照を介してメンバーに直接アクセスすることにあまり関与しないレベルの間接性はありますか?

ありがとう

4

2 に答える 2

1

それはより速いかもしれません(それほどではありませんが)。ただし、どちらの例も、カプセル化を破り、デメテルの法則に違反するという点で正しくありません。クラスまたはそれをインスタンス化する人が、それ自体とその内部のSwitch両方にアクセスできる必要があります。もちろん、すべての部屋にはランプがあり、ランプは部屋内にしか存在できないと仮定しています...つまり、これらの条件が変化した場合、1 つではなく 2 つのクラスを変更する必要があります。RoomLamp

最初の例は次のように書くほうがよいでしょう。

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

その場合、Room何がオンになるかについて責任があります。ランプかもしれないし、ラジオかもしれない。 Switchもう気にする必要はありません。これは遅くなる可能性が高くなりますが、より保守しやすくなります。

Switchのみをオンにする必要がある場合はLamp

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

これは、カプセル化を解除する必要なく、同じくらい高速である必要があります。

于 2011-12-05T18:13:02.190 に答える
0

2 番目の例は、(おそらく) 最初の例よりも高速ではありません。どちらの場合も、TurnOn()呼び出す前に 1 つの参照を解決する必要があります。

于 2011-12-05T17:11:51.080 に答える