Reputation: 523
To clarify, I'm not talking about multi-threaded environment. I often come across a situation where I have to allocate some resources in an init function (and consequently release the resource in a terminate function) and where I would like to avoid calling it twice. I was wondering if there was something like a built-in keyword in C/C++ to make it callable once. Something more sophisticated than a static local variable that I would have duplicated across all my init functions like
static bool isInitialized = false;
if (!isInitialized) {
isInitialized = true;
//...
}
Or maybe it isn't that bad and I could hide this behind a macro CALLABLE_ONCE.
I'm open to any solutions from C/C++03/C++11/C++14.
EDIT:
The reason why I would be using the init/terminate scheme on the global scope would mainly be due to the fact that I tend to create namespaces for entities that shouldn't be instantiated more than once and avoid using singleton as encouraged on this post. Of course using a class would be easier as I would simply use the constructor/destructor, but how can one initialize (only once) this kind of entities(namespaces)?
Upvotes: 2
Views: 797
Reputation: 20771
There is std::call_once
, although presented to be used with threads rather than just one thread application, it can be used by a one thread application too.
The one problem you may encounter is if it throws, then it is not considered initialized. You may protect the initialization function with a try/catch
if required, though.
Also in your case you may want a public static function and another function that is private. The public static function would perform the std::call_once
. Something like this:
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;
};
As you can see, it looks exactly the same as your function, except that the if()
and flag switch are hidden. You could also keep the m_initialized
flag in your first function as a static variable.
The one difference, though, is that the std::call_once
is thread safe.
Upvotes: 2