我想知道是否有可能确保仅在程序的静态初始化步骤中调用函数?
例如,假设我有一些单例类,其中包含std::map
对象,并公开了它的insert
和at
方法。我想确保从其中读取数据(at
方法)是线程安全的,据我所知,这需要确保没有任何东西在修改数据(即,使用insert
方法)。
该映射旨在仅在静态初始化期间填充,此时我假设只有一个线程。一旦insert
开始,有什么方法可以确保我不会误导用户调用main()
?
范例程式码
#include <map>
#include <string>
class Singleton {
private:
std::map<std::string, std::string> m_map;
public:
static Singleton& instance() {
static Singleton theSingleton;
return theSingleton;
}
static bool insert(const std::string& key, const std::string& value) {
return instance().m_map.insert(std::make_pair(key, value) ).second;
}
static std::string at(const std::string& key) {
return instance().m_map.at(key);
}
};
static bool inserted = Singleton::insert("Hello", "World"); // fine
bool addItem(const std::string& key, const std::string& value) {
return Singleton::insert(key, value); // not OK
}
不用说,实际的代码比这个简单的示例要复杂得多。
解决方案后编辑:使其尽可能安全的最佳方法似乎是维护一个
status
变量,该变量记录单例是否处于“插入”或“读取”模式并采取相应措施。感谢大家的想法和建议! 最佳答案
我猜您也想在设置应用程序时使用“at”方法。
为什么不添加一个'lock'方法并在主函数中调用第一个函数那样简单呢?
#include <map>
#include <string>
class Singleton {
private:
std::map<std::string, std::string> m_map;
bool m_locked;
Singleton() : m_locked(false) { }
public:
static Singleton& instance() {
static Singleton theSingleton;
return theSingleton;
}
static void lock() {
instance().m_locked = true;
}
static bool insert(const std::string& key, const std::string& value) {
if (instance().m_locked) { return false; }
return instance().m_map.insert(std::make_pair(key, value)).second;
}
static std::string at(const std::string& key) {
return instance().m_map.at(key);
}
};
static bool inserted = Singleton::insert("Hello", "World"); // fine
bool addItem(const std::string& key, const std::string& value) {
return Singleton::insert(key, value); // not OK
}
int main(int argc, char** argv)
{
Singleton::lock();
Singleton::insert("Hello2", "World2"); // fails
return 0;
}
关于c++ - 是否可以确保仅在 'static initialization'步骤期间调用函数,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53848716/