单例中的所有内容都是静态的吗

Can everything in a singleton be static?

本文关键字:静态 单例中      更新时间:2023-10-16

在C++中,单例中的所有成员是静态的,还是尽可能多?我的想法是,无论如何,全球只有一个实例。

在搜索过程中,我确实发现了很多关于C#中静态类的讨论,但对此并不熟悉。我也想了解一下。

无论你有什么想法,请评论。

对于静态singleton,您无法控制何时分配和构造singleton。这将使您受制于静态变量的构造规则的c++顺序,因此,如果您在构造另一个静态变量时碰巧调用了这个single,那么这个single可能还不存在。

如果您不打算从另一个静态变量的构造函数调用singleton,并且不希望出于任何原因延迟构造,那么为singleton使用静态变量是可以的。

有关更多信息,请参阅静态变量初始化顺序。

您可能知道,singleton模式包含一个静态方法Instance,该方法将在实例存在的情况下创建实例并返回该实例。单例的其他或所有方法都不能是静态的,这是没有道理的。然而,考虑到该类只有一个实例,我不确定将其他所有实例都设置为静态是否有意义。这有道理吗?

单例的主要目的是控制它的创建时间。

对于静态数据成员,您将失去对这些成员的控制。

所以这样做并不明智。

也就是说,单身人士通常是邪恶的&交易;许多问题与纯粹的全球变量相同,包括在不可预测的时间,作为一个不可控制的通信枢纽,将各种不可预测影响从不可预测地点随意传播到其他不可预测且基本上未知的地点。

因此,认真思考一下是个好主意:单例真的是的答案吗?或者,在目前的情况下,它可能只是一种复合本应解决的问题的方法吗?

回答您的问题:您建议的案例更像C#中的"静态类",C++没有"静态类"的概念。

通常在C++单例类中,唯一的静态数据成员是单例实例本身。这可以是指向singleton类的指针,也可以只是一个实例。

有两种方法可以在不将单例实例作为指针的情况下创建单例类。

1)

class MySingletonClass
{
public:
static MySingletonClass& getInstance()
{
static MySingletonClass instance;
return instance;
}
// non-static functions
private:
// non-static data-members
};

2)

class MySingletonClass
{
public:
static MySingletonClass& getInstance()
{
return sInstance;
}
// non-static functions
private:
static MySingletonClass sInstance;
// non-static data-members
};
// In CPP file
MySingletonClass MySingletonClass::sInstance;

这个实现不是线程安全的,在何时构造或何时销毁方面是不可预测的。如果此实例依赖于另一个singleton来销毁自身,则在退出应用程序时可能会导致无法识别的错误。

带指针的看起来像这样:

class MySingletonClass
{
public:
static MySingletonClass& getInstance()
{
return *sInstance;
}
static MySingletonClass* getInstancePointer()
{
return sInstance;
}
MySingletonClass()
{
if (sInstance) {
throw std::runtime_error("An instance of this class already exists");
}
sInstance = this;
}
// non-static functions
private:
static MySingletonClass* sInstance;
// non-static data-members
};

这种单例类的Inialization通常会在应用程序初始化期间发生:

void MyApp::init()
{
// Some stuff to be initalized before MySingletonClass gets initialized.
MySingletonClass* mySingleton = new MySingletonClass(); // Initalization is determined.
// Rest of initialization
}
void MyApp::update()
{
// Stuff to update before MySingletonClass
MySingletonClass::getInstance().update(); // <-- that's how you access non-static functions.
// Stuff to update after MySingletonClass has been updated.
}
void MyApp::destroy()
{
// Destroy stuff created after singleton creation
delete MySingletonClass::getInstancePointer();
// Destroy stuff created before singleton creation
}

尽管在这种情况下可以控制singleton的初始化和销毁,但是singleton在多线程应用程序中不能很好地发挥作用。我希望这能消除你的疑虑。

简短的回答:是的!当然C++是灵活的,几乎所有的事情都是可能的(尤其是这么简单的事情)。

详细的答案取决于您的用例。

  • 其他静态/全局如何取决于您的签名
  • 第一次访问您的singleton的时间(可能在main之前?)
  • 您必须考虑的许多其他事情(其中大多数与您的单例与其他实体的交互有关)