Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/163.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 单例实现:命名空间方法通常比单例类更可取吗?_C++_Static_Namespaces - Fatal编程技术网

C++ 单例实现:命名空间方法通常比单例类更可取吗?

C++ 单例实现:命名空间方法通常比单例类更可取吗?,c++,static,namespaces,C++,Static,Namespaces,(这个问题假设一个全局+唯一对象是目标。我想澄清的是,这并不意味着它在询问或鼓吹是否/为什么/何时使用/不使用单例或全局。) 我想知道我是否缺少一个C++的技术性,所以我的问题是: 是C++中的单模式模式的命名空间实现吗?如果是这样的话,有什么原因不经常被认为是更好的方法吗? 从Google的样式指南中,我们可以看到命名空间非成员函数优于静态成员函数,但仅当不共享静态数据时: “而不是创建仅用于分组静态成员函数的类 如果不共享静态数据,请改用名称空间。“ 为什么不让非成员函数共享在未命名命名空

(这个问题假设一个全局+唯一对象是目标。我想澄清的是,这并不意味着它在询问或鼓吹是否/为什么/何时使用/不使用单例或全局。)

我想知道我是否缺少一个C++的技术性,所以我的问题是:

<强>是C++中的单模式模式的命名空间实现吗?如果是这样的话,有什么原因不经常被认为是更好的方法吗?

从Google的样式指南中,我们可以看到命名空间非成员函数优于静态成员函数,但仅当不共享静态数据时:

“而不是创建仅用于分组静态成员函数的类 如果不共享静态数据,请改用名称空间。“

为什么不让非成员函数共享在未命名命名空间中声明的静态数据?这有什么不对吗?这解释了为什么名称空间通常不被推荐为编写C++中的单类的更好的选择? 因为我找不到命名空间方法的建议,但是尽管C++没有强制使用类:

,但是很容易找到类方法。

使用源文件中包含未命名命名空间的命名命名空间:

  • 您可以通过静态数据获得“状态”
  • 您可以获得将内容放入未命名名称空间的额外隐私
  • 您仍然可以通过使用静态指针和从函数调用构造来控制其静态对象的构造顺序
  • 您不需要实现单例类

编辑-我所想的名称空间方法示例:

单件事。h:

namespace single_thing   // The singleton (if this is actually valid)
{
    void GrowSomeCats(int amount); // Typical setter
    int GetNumCats();              // Typical getter
}
SingleThing.cpp:

#include "Balloon.h"

namespace // Acting like private members and functions
{   
    int numCats = 4;        // POD
    Balloon* wilson = NULL; // Not POD (and not a singleton)

    // Contrived 'private' function
    bool CanGrowCats()      
    { return wilson && wilson->LikesCats(); }

    // Contrived excuse to instantiate non-POD 'members'
    void RandomlyCreateOtherObjects()
    {
        if (!wilson /* && someRandomiserImTooLazyToType()*/ )
            wilson = new Balloon();
    }
}

namespace single_thing  // 'Public' functions
{
    void GrowSomeCats(int amount)
    {
        RandomlyCreateOtherObjects();
        if (CanGrowCats()) 
            numCats += amount;
    }

    GetNumCats()
    { return numCats; }
}

单例设计模式是关于创建有用类的唯一实例(不需要创建无用对象)。在C++类中,用<代码>类< /代码>和<代码>结构> <代码>关键字定义。为了使单例类有用,除了创建和销毁之外,还应该实现一些对实例进行操作的方法。为了确保奇点,单例类应该隐藏其构造函数并公开用于访问实例的静态方法

仅使用名称空间将无法定义单例的有用方法。将实例访问方法实现为命名空间中的函数而不是类本身是可能的,但是需要“友好”该函数,并且没有意义,因为类已经定义

实现非对象单例(例如普通数据类型)将假定实例不需要构造,因此不需要单例。

(我假设我们可以同意全局状态是一个危险的东西,必须特别小心使用。)

从技术上讲,您的单例名称空间相当于一个单例类。然而,它有一个主要的缺点,在我看来,它是不可能的:它隐藏了一个事实,即它是有状态的。是否使用过
std::strok()
?还记得那是多么糟糕的一团吗?那是因为它也隐藏了它的庄严


由于全局状态本质上是危险的,因此任何使用它的功能都应该在调用站点上充分明确这一事实,最好是使用语言构造——因为没有人阅读注释或文档。A
Foo::instance()->do_work()
是一种已知的模式,它清楚地表明正在发生一些特殊的事情;a
foo::do_work()
没有。

我不知道你为什么说使用名称空间方法无法编写有用的方法。你如何设想从名称空间函数访问实例?(当时无意中按了enter键)。你已经谈到了“实例”一词,但我想问的是一种根本不使用特定实例的名称空间方法。也许值得澄清的是,我的理解是,单身是一个概念;singleton类是它的一个实现,我想问的是另一个实现。我将编辑Q以澄清。:)如果没有实例,为什么会需要单例设计模式?问题编辑为显示未使用单例类/实例实现的单例示例。这似乎是一个关于面向对象编程优点的问题,是否值得将相关状态和函数合并到一个“类”中。事实上,我认为它也恰好是一个单例,这与此无关。请注意,这不是线程安全的。我建议你查一下迈耶的单身汉。非常感谢,两条有用的评论。非常感谢你在不被单身/全球假设分心的情况下提出了两个粗体的问题。现在我可以看出,我并不是纯粹在技术上做错了什么,但这有一个有意义的缺点。强制性免责声明。强制性免责声明。