我想知道是否有可能确保仅在程序的静态初始化步骤中调用函数?

例如,假设我有一些单例类,其中包含std::map对象,并公开了它的insertat方法。我想确保从其中读取数据(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/

10-13 05:05