【问题标题】:static object vs singleton class object in c++?C ++中的静态对象与单例类对象?
【发布时间】:2013-12-29 19:43:10
【问题描述】:

我只想知道什么时候应该在静态对象上使用单例类,反之亦然。因为相同可以用于只有一个实例。 我可以猜测内存存储差异的原因之一。 是否有任何其他理由选择其中一个。

【问题讨论】:

  • 在许多情况下,单例实际上是作为具有静态变量的类来实现的。在多线程环境中,我相信当前的 c++ 标准不能确保实现是有效的。在任何其他情况下,您可以使用“静态”实现:stackoverflow.com/questions/1008019/c-singleton-design-pattern
  • 不应该也不要使用!如果您绝对必须使用函数本地静态对象可能会更好。
  • @DietmarKühl:一个函数本地静态对象 = Meyers 的单例。 ;-)
  • @Cheersandhth.-Alf: int& f() { static int rc{}; return rc; } - 这使得int 成为某种单身......?!?
  • @DietmarKühl:是的。在 Scott Meyers 之后,它被称为“Meyers”。它的主要问题是,对于类类型,它可能过早地被销毁,例如在启动退出后记录一些关键内容之前释放自身的日志记录工具。在c++03里面也有线程问题,见stackoverflow.com/questions/1661529/…哦,想想可能还有线程问题……

标签: c++ singleton


【解决方案1】:

单例和静态对象的主要区别在于,单例保证只能有一个特定类类型的实例,而静态对象只有一个特定的实例类型。这意味着根本区别在于 是否具有多个实例是否有意义。例如,假设您有一个构建小部件的工厂。

class WidgetFactory {
    public:
        int numberOfWidgetsBuiltInTheWholeApplication();
            // returns number_of_widgets_built
        std::shared_ptr<Widget> build();
            // increments number_of_widgets_built
    private:
        size_t number_of_widgets_built;
};

我们还假设我们要保证我们可以确定在整个应用程序中创建的 Widget 的数量,并且强制只有一个 WidgetFactory 是一种简单的方法。这是我们将使用单例的地方。如果我们只使用一个静态对象,像这样:

WidgetFactory& theWidgetFactory()
{
    static WidgetFactory widget_factory;
    return widget_factory;
}

我们无法保证 theWidgetFactory().numberOfWidgetsBuiltInTheWholeApplication() 确实是真正的总数,因为其他人可能会出现并创建自己的 WidgetFactory 实例。

但是,如果我们让 WidgetFactory 成为单例,我们现在就有了保证。我们可以通过将构造函数设为私有来做到这一点:

class WidgetFactory {
    public:
        int numberOfWidgetsBuiltInTheWholeApplication();
        std::shared_ptr<Widget> build();
    private:
        WidgetFactory();
        WidgetFactory(const WidgetFactory &); // not implemented
        friend WidgetFactory& theWidgetFactory();
};

现在只允许theWidgetFactory() 函数创建实例。还有其他方法可以让numberOfWidgetsBuiltInTheWholeApplication() 在不使用单例的情况下正常运行,但在某些情况下,解决方案可能更复杂或有其他缺点。

【讨论】:

  • 沃恩。如果我想限制这个类只能创建 5 个对象。那么方法是什么?
  • @vivekjain:一种方法是拥有 5 个友元函数,每个函数返回五个实例之一。
【解决方案2】:

如果只涉及静态初始化,则可以使用全局常量。在涉及动态初始化的情况下,您要避免使用static initialization fiasco。因此,如果必须,应该首选单例。

然而,可变单例通常只是伪装的全局变量。

因此,尽可能避免使用它们。

【讨论】:

    猜你喜欢
    • 2011-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-14
    • 1970-01-01
    • 2011-02-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多