我有一个基类的成员函数,我只想在类的第一个实例的初始化上调用[once](无论它是基类的直接实例,还是继承类)。基本上,我想避免不必要的函数调用。
答案 0 :(得分:7)
仅在第一次发生某事时才完成的事情是在第一次执行周围函数期间初始化函数局部静态。那你怎么做呢:
class X {
static int firstInitFunc();
public:
X() {
static int onFirstCtorCall = firstInitFunc();
}
};
现在第一次创建X
时,onFirstCtorCall
将被初始化(线程安全),调用该函数。 X
的任何后续创建都不会再次调用该函数。
如果X
上有多个构造函数,您仍然只需要对该函数进行一次调用。您可以通过使用静态变量委托构造函数或使用另一个静态函数来实现:
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();
}
};
更新:我会选择juanchopanza的评论,并使用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);
}
};
注意返回类型:在函数调用初始化函数本地静态的情况下,该函数必须返回一个值,静态将被初始化。相反,使用std::call_once
函数可能不具有返回类型,因为不会评估任何返回值。
答案 1 :(得分:2)
简单的解决方案:
class C
{
private:
static bool runOnce;
public:
C()
{
if (!C::runOnce)
{
C::runOnce = true;
RunSth();
}
}
};
bool C::runOnce = false;