Reputation: 21
I have a member function for a base class that I only want to be called [once] on the initialization of the first instance of the class (whether it be a direct instance of the base class, or an inherited class). Basically, I want to avoid unnecessary function calls.
Upvotes: 2
Views: 2393
Reputation: 24596
A thing that is done only done during the first time something happens is the initialization of function local statics during the first execution of the surrounding function. So how you could do it:
class X {
static int firstInitFunc();
public:
X() {
static int onFirstCtorCall = firstInitFunc();
}
};
Now the first time you create an X
, onFirstCtorCall
will be initialized (threadsafe), calling the function. Any following creation of X
won't call that function again.
If you have multiple constructors on X
, you'll still want only one call to the function. You can achieve that by either delegating to the constructor with the static variable or by using another static function:
class X {
static int firstInitFunc();
public:
X() {
static auto onFirstCtorCall = firstInitFunc();
}
X(int) : X() // delegate to X()
{ /* ... */ }
};
class X {
static int firstInitFunc();
static void callFirstInit() {
static int onFirstCtorCall = firstInitFunc();
}
public:
X() {
callFirstInit();
}
X(int) {
callFirstInit();
}
};
Update: I'll pick up juanchopanza's comment and provide an example using std::call_once
:
class X {
static void firstInitFunc(); //see note to return types
static std::once_flag firstInitFlag;
public:
X() {
std::call_once(firstInitFlag, firstInitFunc);
}
X(int) {
std::call_once(firstInitFlag, firstInitFunc);
}
};
Note to return types: While in the case of function local statics' initialization used for the function call, that function must return a value, with wich the static will be initialized. In contrast, with std::call_once
the function may not have a return type, because any returned value will not be evaluated.
Upvotes: 7
Reputation: 25927
Simple solution:
class C
{
private:
static bool runOnce;
public:
C()
{
if (!C::runOnce)
{
C::runOnce = true;
RunSth();
}
}
};
bool C::runOnce = false;
Upvotes: 2