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()涉及额外的间接级别,因为我们需要遵循对房间的引用。它是否正确?如果可以内联调用(通过显式内联或链接器级别的整个程序优化),是否会删除额外的间接调用?或者,换一种说法,是否可以通过将 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类或实例化它的任何人都可以访问它Room本身和Lamp它的内部。当然,我们还假设每个房间都有一盏灯,并且一盏灯只能存在于一个房间内……这意味着如果这些条件发生变化,有两个类需要改变,而不仅仅是一个。

第一个例子最好写成

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打开 a 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

您的第二个示例(可能)不会比第一个示例快。在这两种情况下,都需要先解析一个引用,然后TurnOn()才能调用。

于 2011-12-05T17:11:51.080 回答