【问题标题】:How to force a usage style for a singleton class如何强制单例类的使用风格
【发布时间】:2013-06-26 07:43:11
【问题描述】:

假设我们有一个单例类,其中的 Instance 函数(返回该类的单例实例的函数)已被重载。一个版本接受一些参数,并在类构造函数中初始化对象,另一个版本不接受任何参数。

1.    myClass::Instance ( int x, int y );
2.    myClass::Instance ( );

我们想要实现的是类的用户应该总是首先调用 (1),并且任何后续调用都应该只对 (2) 进行。不应允许用户第一次调用 (2),一旦调用 (1),就不允许对 (1) 进行后续调用。

是否可以在不将检查 NULL 指针的负担放在类的用户身上来实现这一点?

【问题讨论】:

  • 显然,第一个问题应该是,你可以不用 Singleton 吗?
  • 单例类solely 确保实例在请求时可用。你的没有(是的,它可用,但你必须先调用这个函数)。如果创建实例的责任在于用户,那么您根本就没有单例(这可能是也可能不是坏事)。
  • @Matthieu M. 不幸的是,在这种情况下需要 Singleton。
  • @n.m.传递给类的参数位于 main(); HWND 和 HINSTANCE (winapi) 以及我们的单例类无法访问这些参数,因此保存参数并将实例返回给用户的单例是否有意义?
  • @StudentX:我同意它可能会变得乏味,但在许多情况下,显式优于隐式。例如,如果您想重新设计您的应用程序以拥有两个窗口而不是一个窗口,该怎么办?然后你将有两个HWND 句柄,根据哪个是活动的,程序应该绘制到一个或另一个。你不能用一个单例来做到这一点......而如果你明确地传递句柄,那将是微不足道的。全局变量(如Singleton)隐藏了数据流,并引入了不可见的依赖关系,这就是它们Bad(tm)的原因。

标签: c++ oop design-patterns singleton


【解决方案1】:

问题是你不可能让编译器在编译时仲裁这个“第一次调用”概念(因为它编译一个特定的翻译单元,它不知道 (1) 是否可以从其他一些翻译单元),所以你必须:

  • 设计为在编译时限制对一个或两个重载的访问,和/或
  • 在运行时检查有效使用情况,和/或
  • 让您的代码更能容忍对 (1) 的多次调用,同时确保获得所需的行为。

有许多可能的方法可能足够,也可能不够:

  • 您可以 (1) 通过将其设为受保护或私有来更难访问,同时授予将调用它的特定代码的友谊,保留 (2) 公开以方便代码的其他部分持续使用

  • 您可以编写 (1) 的代码,以便在第一次之后忽略任何参数并调用 (2)

  • 您可以在运行时使用断言来验证使用情况,这有望确保客户端代码在投入生产之前很久就符合您的条件

  • 您可以 (1) 返回调用 (2) 所需的内容,例如客户端无法以其他方式创建的类型的对象,但仅此一项并不能阻止 (1)再次被调用。所需的对象可能会传递给 (2) 的构造函数,或者 (2) 可能成为该对象的函数。

【讨论】:

  • +1 表示“设计以在编译时限制对一个或两个重载的访问”。
【解决方案2】:

在 1. 如果实例已经存在,则抛出异常(例如 std::logic_error )。 如果没有,则使用提供的参数构造实例并返回它。

在 2 中。 如果实例尚不存在,则抛出异常(例如 std::logic_error)。那就退货吧。

【讨论】:

    【解决方案3】:

    您可以为此使用 std::call_once (http://en.cppreference.com/w/cpp/thread/call_once)。您将需要一个 once_flag (http://en.cppreference.com/w/cpp/thread/once_flag) 私有成员(例如 m_once_flag)。

    在 1 中:您将您的实现包装在一个 call_once 周围,并将 m_once_flag 作为第一个参数。

    在 2 中:你呼叫 1。

    call_once 会注意该函数只在第一次执行。

    【讨论】:

      猜你喜欢
      • 2015-03-18
      • 1970-01-01
      • 1970-01-01
      • 2012-09-25
      • 2011-12-03
      • 2022-01-12
      • 2014-07-06
      • 2010-09-27
      • 1970-01-01
      相关资源
      最近更新 更多