Singleton实现:与Singleton类相比,名称空间方法通常更可取吗



我想知道我是否遗漏了C++的技术细节,所以我的问题是:

C++中singleton模式的命名空间实现有效吗?如果是这样的话,有没有理由不经常建议将其作为更好的方法

从谷歌的风格指南中,我们看到命名空间非成员函数比静态成员函数更受推荐,但仅当不共享静态数据时:

"而不是只创建类来对静态成员函数进行分组不共享静态数据的服务器使用名称空间。">

为什么不让非成员函数共享在未命名命名空间中声明的静态数据?这是否解释了为什么命名空间通常不被建议作为用C++编写单例类的更好替代方案?

因为我找不到命名空间方法的建议,但尽管C++没有强制使用类,但很容易找到类方法:

C++Singleton设计模式

有人能给我一个c++中Singleton的例子吗?

声明为GetInstance方法的静态变量的Singleton实例

http://www.aristeia.com/Papers/DDJ_Jul_Aug_2004_revised.pdf

辛格尔顿:应该如何使用

在源文件中使用带有未命名名称空间的命名名称空间:

  • 您可以通过静态数据获得"state">
  • 将事物放入未命名的名称空间可以获得额外的隐私
  • 您仍然可以通过使用静态指针和从函数调用进行构造来控制其静态对象的构造顺序
  • 您不需要实现singleton类

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

SingleThing.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; }
}

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

从技术上讲,您的singleton命名空间等效于singleton类。然而,它有一个主要缺点,在我看来,这是不可行的:它隐藏了它是有状态的事实是否使用过std::strtok()?还记得那是多么糟糕的混乱吗?这是因为它也隐藏了它的状态。

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

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

仅使用名称空间将无法定义singleton的有用方法。将实例访问方法实现为命名空间中的函数而不是类本身是可能的,但需要对该函数进行"friending",这是没有意义的,因为类已经定义。

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

最新更新