У меня есть функция-член для базового класса, которую я хочу вызывать [один раз] при инициализации первого экземпляра класса (будь то прямой экземпляр базового класса или унаследованный класс). По сути, я хочу избежать ненужных вызовов функций.
То, что делается только в первый раз, когда что-то происходит, — это инициализация локальной статики функции во время первого выполнения окружающей функции. Итак, как вы могли это сделать:
class X {
static int firstInitFunc();
public:
X() {
static int onFirstCtorCall = firstInitFunc();
}
};
Теперь в первый раз вы создаете X
, onFirstCtorCall
будет инициализирован (threadsafe), вызывая функцию. Любое последующее создание 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();
}
};
Обновить: Я заберу комментарий Джанхопанзы и приведу пример, используя 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
функция может нет иметь возвращаемый тип, потому что любое возвращаемое значение не будет оцениваться.
Простое решение:
class C
{
private:
static bool runOnce;
public:
C()
{
if (!C::runOnce)
{
C::runOnce = true;
RunSth();
}
}
};
bool C::runOnce = false;