如何强制单例类的使用方式

时间:2013-06-26 07:43:12

标签: c++ oop design-patterns singleton

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

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

我们想要实现的是,类的用户应该始终首先调用(1),并且任何后续调用都应该只调用(2)。不应允许用户首先拨打(2),一旦拨打(1),不允许后续拨打(1)。

是否有可能实现这一点而不必在类的用户身上检查NULL指针的负担?

3 个答案:

答案 0 :(得分:3)

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

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

有许多可能或不充分的方法:

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

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

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

  • 你可以(1)返回需要调用的东西(2),例如客户端无法创建的类型的对象,但仅此一项不会阻止(1)再次被召唤。可以将所需对象传递给(2)的构造函数,或者(2)可能成为该对象的函数。

答案 1 :(得分:2)

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

2。 如果实例尚不存在,则抛出异常(例如std :: logic_error)。然后你回来了。

答案 2 :(得分:0)

您可以使用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中:您使用m_once_flag作为第一个参数将您的实现包装在call_once周围。

2:你打电话给1.

call_once将注意该函数仅在第一次执行时执行。