C++从另一个成员间接访问成员

发布于 2024-12-19 18:07:54 字数 830 浏览 7 评论 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() 涉及额外的间接级别,因为我们需要遵循对 room 的引用。这是正确的吗?如果可以内联调用(通过显式内联或链接器级别的整个程序优化),是否会删除额外的间接寻址?或者,换句话说,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(); }
}

或者,更一般地说,如果持有对对象的引用,是否存在间接级别,而不是直接通过引用访问其成员通过参考,然后通过成员?

谢谢

Given the following example code:

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

My understanding here is that the second TurnOn() involves an extra level of indirection, as we need to follow the reference to room. Is this correct? Will that extra indirection be removed if the call can be inlined (either via explicit inlining, or whole program optimization at linker level)? Or, put differently, could the TurnOn function in Switch be sped up by changing it to:

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

Or, more generally, if holding a reference to an object, is there a level of indirection less involved in accessing its members directly via a reference rather than via the reference and then the member?

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

埋葬我深情 2024-12-26 18:07:54

可能会更快(尽管不会快很多)。然而,这两个例子都是不正确的,因为它们破坏了封装并违反了德米特法则。它们要求 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 仅打开 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;
};

这应该同样快,而不需要我们破坏封装。

It might be faster (though not by much). However, both examples are incorrect in that they break encapsulation and violate the Law of Demeter. They require that either the Switch class or anyone who instantiates it have access to both the Room itself and the Lamp inside of it. Of course, we're also assuming that every Room has a Lamp, and that a Lamp can only ever exist within a Room...which means if those conditions ever change, there's two classes to change instead of just one.

The first example would be better written as

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

as then the Room is responsible for what gets turned on. Could be a lamp, could be a radio. Switch doesn't have to care anymore. This is more likely to be slower, but it's more maintainable.

If you want to require that Switch only turn on a Lamp, then

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

This should be just as fast, without requiring that we break encapsulation.

2024-12-26 18:07:54

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

Your second example will (probably) be no faster than the first example. In both cases, one reference needs to be resolved before TurnOn() can be invoked.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文