友谊的替代品?

发布于 2024-12-12 16:19:46 字数 452 浏览 2 评论 0原文

在下面的场景中除了友谊还有其他选择吗?

我有一个代表 UI 窗口的 Window 类。此外,一个作为单例实现的 WindowManager 类管理我的应用程序中的所有窗口对象(呈现 UI、调度事件等)。

WindowManager 将具有一个公共接口仅由其单例实例化方法和函数组成,用于呈现 UI 和分派 UI 事件。

我还希望 Window 对象在构造期间向 WindowManager 注册,并在销毁期间取消注册。 WindowManager::registerWindowManager::deregister 方法将是私有的或受保护的,因为我不想要客户端(除了 Window 对象) ) 才能使用此接口。

在这种情况下,有没有办法避免 Window 和 WindowManager 之间的友谊?也许用完全不同的方式来达到类似的结果?

Is there any alternative to friendship in the following scenario?

I have a Window class which represents an UI window. Also, a WindowManager class, implemented as a singleton, manages all window objects in my application (renders the UI, dispatches events, etc.)

The WindowManager will have a public interface consisting of only its singleton instancing method and functions to render the UI and to dispatch an UI event.

I would also like Window objects to register with the WindowManager during construction and to de-register during destruction. The WindowManager::register and WindowManager::deregister methods will be either private or protected, because I do not want clients (other than Window objects) to be able use this interface.

Is there a method to avoid friendship between Window and WindowManager in this case? Perhaps a totally different way to achieve similar results?

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

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

发布评论

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

评论(5

东北女汉子 2024-12-19 16:19:47

是的,但友谊是最好的解决方案,因为它是为这种情况设计的。

另一种方法是使 Window 成为 WindowManager 的成员(注意,这需要新的 C++11 辅助功能规则)。或者让它从 WindowManager 的成员派生。或者让它从 WindowManager 本身派生。

您还可以将私有类型放入 Window 中,在 Window 中嵌套一个键类型,该键类型只能从该私有类型构造,并且需要传递该键类型的实例到WindowManager。这应该适用于 C++11 之前的编译器。

当然,任何方法都可以通过足够的强制转换来绕过。

Yes, but friendship is the best solution, since it's designed for this scenario.

Another way is to make Window a member of WindowManager (note, this requires the new C++11 accessibility rules). Or have it derive from a member of WindowManager. Or have it derive from WindowManager itself.

You can also put a private type inside Window, make a key type nested in Window which can only be constructed from that private type, and require passing an instance of that key type to WindowManager. This should work in pre-C++11 compilers.

Of course, any approach can be bypassed using enough casting.

瑾兮 2024-12-19 16:19:47

在这里使用Friendlyship 似乎是合适的。您想要指示两个类之间的有意的强耦合,这可以通过 Friends 来恰当地指示。

更具体地说,一个类需要访问另一个类的内部结构,并且您不希望使用公共访问说明符向每个人授予访问权限。

经验法则:公共太弱而私有太强,您需要某种形式的选定访问:受保护或朋友。

使用Friendshipship 是最好的解决方案。

Using Friendship seems appropriate here.You want to indicate an Intentional strong coupling between the two classes, which is aptly indicated through friends.

More specifically, one class needs access to another classes's internals and you don't want to grant access to everyone by using the public access specifier.

The rule of thumb: is public is too weak and private is too strong, you need some form of selected access: either protected or friend.

Using Friendship is the Best solution here.

御守 2024-12-19 16:19:47

使用嵌套类。

WindowManager {
  private:
    static void construct();
    static void destruct();
  public:
    class InternalWindow { // can access WindowManager's private members (no scoping needed)
      InternalWindow() { construct(); }
      ~InternalWindow() { desstruct(); }
    };
};

typedef WindowManager::InternalWindow Window; // to make scoping easier

Use nested classes.

WindowManager {
  private:
    static void construct();
    static void destruct();
  public:
    class InternalWindow { // can access WindowManager's private members (no scoping needed)
      InternalWindow() { construct(); }
      ~InternalWindow() { desstruct(); }
    };
};

typedef WindowManager::InternalWindow Window; // to make scoping easier
神魇的王 2024-12-19 16:19:47

另一个解决方案(不一定更好:])是将窗口注册到一个单独的组件 - 比方说 WindowRegister。 WindowRegister 可以有一个用于注册的公共接口,也可以是 WindowManager 的私有成员。

友谊的问题在于它不是继承的(我爷爷的朋友不一定是我的朋友)——而且 Window 或 WindowManger 很有可能是多态的。

问候

Another solution (not necessary better :]) is to put the window registration to a separate component - let's say the WindowRegister. WindowRegister can have a public interface for registration and can also be a private member of a WindowManager.

The problem with friendship is that it is not inherited (a friend of my grandpa is not necessary my friend) - and there is a big chance that either Window or WindowManger will be polymorphic.

Regards

假面具 2024-12-19 16:19:47

还有其他几种选择。例如:

  • 您可以使用指针数学、汇编代码和有关内存中类布局的知识来在运行时调用私有方法。然而,这不是很便携。
  • 您可以将该方法公开,但要求它采用由 Window 类中的私钥加密签名的参数,从而防止其他类能够实际调用该方法并让它执行任何操作。
  • 您可以使该方法受到保护,并使一个方法从另一个方法继承。
  • 您可以创建一个共同的超类,它们都继承自该超类,并使用其中的受保护方法在它们之间进行通信。
  • 您可以使用很少使用的“enemy”关键字来允许他们运行彼此的私有方法,但前提是他们拥有使其他班级有罪的勒索材料。 (好吧,这不是一个真正的语言功能,但它应该是。)

或者你可以让他们成为朋友。这比任何其他选择都更容易、更明智,也是朋友存在的原因。

There are several other options. For example:

  • You could use pointer math, assembly code, and knowledge about the layout of the classes in memory to call private methods at runtime. This, however, is not very portable.
  • You could make the method public, but require that it take a parameter cryptographically signed by a private key which lives in the Window class, thus preventing other classes from being able to actually call the method and have it do anything.
  • You could make the method protected and make one inherit from the other.
  • You could make a common superclass which they both inherit from and use protected methods from it to communicate between them.
  • You could use the little used "enemy" keyword to allow them to run each other's private methods, but only when they have blackmail material which incriminates the other class. (Okay, that's not a real language feature, but it should be.)

Or you could just make them friends. That's much easier and saner than any of the other options and why friends exist.

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