c++ - 初学者的 C++ 线程安全单例设计
问题描述
我希望创建一个静态 Class 对象,该对象应在程序运行时保留在内存中。该对象只需要由 init 函数初始化一次,并且输出函数将始终在静态方法中调用。我的代码有意义吗?它是线程安全的吗?
class Singleton
{
public:
static void init(const int value)
{
static Singleton inst;
inst.Value = value;
}
static int prnValue()
{
return Value;
}
private:
Singleton() {};
static int Value;
};
int main()
{
int inputValue = 10;
Singleton::init(inputValue);
cout << Singleton::prnValue();
return 0;
}
新编辑: 或者我可以这样尝试吗?
class Singleton
{
public:
static Singleton& init(const int value)
{
static Singleton inst;
inst.Value = value;
return inst;
}
static int prnValue()
{
return Value;
}
private:
Singleton() {};
static int Value;
};
加法: Meyer 的单例示例看起来像
class Singleton
{
public:
static Singleton& init()
{
static Singleton inst;
return inst;
}
private:
Singleton() {};
};
那么我的代码与 Meyer 的示例不一致吗?
Try4: 这个怎么样?
class Singleton
{
public:
static Singleton& init(int value)
{
static Singleton inst(value);
return inst;
}
static int prnValue()
{
return Value;
}
private:
Singleton(value)
{
Value = value;
}
int Value;
};
添加评论: 如何在单例中传递参数 似乎提供了与 Try4 相同的答案。
解决方案
放弃 Singleton 并Value
使用const
辅助函数初始化全局变量。
例子:
// anonymous namespace to bind the global to this file to prevent the static
// initialization order fiasco
namespace
{
const int Value = ReadIniFile("section", "key", default_value);
}
但是如果你需要在其他文件中使用这个变量呢?我得到的最好的建议是不要。但是如果你必须的话,静态初始化顺序的失败需要被克服。这是一种与您目前看到的类似的快速方法:
// Lazy loader function similar to Meyers Singleton
int Value()
{
static int value = ReadIniFile("section", "key", default_value);
return value;
}
用法:
me_function_need_Value(Value());
这确保Value
在任何人尝试使用它之前初始化它,无论项目中的哪个文件需要它。不幸的是,现在很难弄清楚它何时超出范围,因此问题并没有真正消失。它只是从程序的开头移到了更易于管理的结尾。请参阅C++ 中静态对象的破坏顺序。确保退出Value
后没有人使用main
,您将是安全的。不过,请谨慎使用。
推荐阅读
- javascript - Blockly Mutator 变量未更新
- django - 获取Django模型对象后进行数据转换
- python - Gmail API - 从 g-suite 服务帐户发送邮件时设置发件人名称
- node.js - 用fluent-ffmpeg创建GIF,覆盖不显示?
- list - 将整个数据列表插入到 xamarin.android 中的 sql 数据库表中
- sql - 查找最流行的 SQL 组合
- mongodb - 如何从 mongo 领域应用程序中导出当前应用程序用户?
- flutter - 如何根据 --dart-define 参数构建具有不同图标的 Flutter 应用程序
- asp.net - Ocelot + consul + my web api (.Net 5) via HTTPS in docker
- macos - 创建devcontainer时如何获取ARM Docker镜像是VS Code?(麦克米1)