C++ 仅在初始化类(C+;+;)的第一个实例时调用成员函数
我有一个基类的成员函数,我只希望在初始化该类的第一个实例时调用它(无论它是基类的直接实例还是继承的类)。基本上,我希望避免不必要的函数调用。简单解决方案:C++ 仅在初始化类(C+;+;)的第一个实例时调用成员函数,c++,inheritance,member-functions,C++,Inheritance,Member Functions,我有一个基类的成员函数,我只希望在初始化该类的第一个实例时调用它(无论它是基类的直接实例还是继承的类)。基本上,我希望避免不必要的函数调用。简单解决方案: class C { private: static bool runOnce; public: C() { if (!C::runOnce) { C::runOnce = true; RunSth(); } }
class C
{
private:
static bool runOnce;
public:
C()
{
if (!C::runOnce)
{
C::runOnce = true;
RunSth();
}
}
};
bool C::runOnce = false;
只有在第一次发生事件时才做的一件事是在第一次执行周围函数时初始化函数局部静态。那么你如何做到这一点:
class X {
static int firstInitFunc();
public:
X() {
static int onFirstCtorCall = firstInitFunc();
}
};
现在,当您第一次创建X
时,onFirstCtorCall
将被初始化(threadsafe),调用函数。任何后续创建的X
都不会再次调用该函数
如果在X
上有多个构造函数,您仍然只需要对函数进行一次调用。您可以通过将静态变量委托给构造函数或使用另一个静态函数来实现这一点:
C++11:
C++03:
更新:我将听取juanchopanza的评论,并使用std::call_once
提供一个示例:
C++11使用call_一次
返回类型注意:如果函数调用使用函数本地statics的初始化,则该函数必须返回一个值,该值将初始化静态。相比之下,使用
std::call_once
函数可能没有返回类型,因为任何返回值都不会被计算。看看。如果您不想/不能使用c++11,或者您认为juanchopanza提出的解决方案过于高明,您可以使用一个静态bool标志来指示函数已经运行,并且不再运行它。我认为应该结合上面两个注释来回答:-)它甚至不必是类的静态数据成员;它也可能是一个局部静态变量。是否有更干净的标准方法?不需要对每个实例和添加的var进行条件检查就可以做到这一点吗?我知道我对一个字节有点吹毛求疵。。。但我想学习如何编写干净的代码。@PhillipWeber“对一个字节有点挑剔”干净的代码。C++11的std::run_once
,有一种更简洁的方法,尽管它也需要一些存储。@PhillipWeber参见Arne的答案:)@PhillipWeber关键是,有时为了保持代码整洁,必须使用额外的变量。+1线程安全性由[stmt.dcl]/4保证;尽管std::run\u once
可能更惯用。@DyP添加了一个std::run\u once
solution@ArneMertz+1:-)回答得好。
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();
}
};
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);
}
};