наследование — функция-член, вызываемая только при инициализации первого экземпляра класса (C ++)

У меня есть функция-член для базового класса, которую я хочу вызывать [один раз] при инициализации первого экземпляра класса (будь то прямой экземпляр базового класса или унаследованный класс). По сути, я хочу избежать ненужных вызовов функций.

2

Решение

То, что делается только в первый раз, когда что-то происходит, — это инициализация локальной статики функции во время первого выполнения окружающей функции. Итак, как вы могли это сделать:

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 функция может нет иметь возвращаемый тип, потому что любое возвращаемое значение не будет оцениваться.

7

Другие решения

Простое решение:

class C
{
private:
static bool runOnce;

public:
C()
{
if (!C::runOnce)
{
C::runOnce = true;
RunSth();
}
}
};

bool C::runOnce = false;
2

По вопросам рекламы [email protected]