有没有办法让全局函数/静态成员函数可调用一次?

时间:2017-02-18 17:59:51

标签: c++ c c++11 initialization c++14

澄清一点,我不是在谈论多线程环境。我经常遇到一种情况,我必须在init函数中分配一些资源(并因此在终止函数中释放资源),并且我希望避免两次调用它。我想知道在C / C ++中是否有类似内置关键字的东西可以让它一次调用。比我在所有init函数中重复的静态局部变量更复杂的东西,比如

static bool isInitialized = false; 
if (!isInitialized) {
  isInitialized =   true;
//...
} 

或许它不是那么糟糕,我可以隐藏在宏CALLABLE_ONCE后面。

我对C / C ++ 03 / C ++ 11 / C ++ 14中的任何解决方案持开放态度。

修改

我之所以在全局范围内使用init / terminate方案,主要是因为我倾向于为不应该多次实例化的实体创建名称空间,并避免使用单独的鼓励this post。当然使用类会更容易,因为我只是使用构造函数/析构函数,但是如何初始化(只有一次)这种实体(名称空间)?

1 个答案:

答案 0 :(得分:1)

std::call_once,虽然它只用于线程而不是一个线程应用程序,但它也可以由一个线程应用程序使用。

您可能遇到的一个问题是,如果它抛出,则不会被视为已初始化。如果需要,您可以protect the initialization function try/catch

同样在您的情况下,您可能需要一个公共静态函数和另一个私有函数。公共静态函数将执行std::call_once。像这样:

class my_class
{
public:
  static void init()
  {
     std::call_once(m_initialized, private_init);
  }

private:
  static void private_init()
  {
     ... // init here
  }

  static std::once_flag   m_initialized;
};

如您所见,它看起来与您的函数完全相同,只是隐藏了if()和flag开关。您还可以将第一个函数中的m_initialized标志保留为静态变量。

但唯一的区别是std::call_once是线程安全的。