Я нашел этот вопрос , который просит способ выполнить кусок кода только один раз. И был хороший ответ, который гласит объявить переменную stati c bool и инициализировать ее значение лямбда-функцией, которая запускает код, который должен быть выполнен только один раз, и возвращает true. Возвращаемое значение просто для инициализации переменной stati c с помощью, поскольку у вас не может быть локальной переменной с типом void
.
Код выглядит так:
#include <iostream>
class X
{
public:
X()
{
std::cout << "Constructed." << std::endl;
}
void Func()
{
std::cout << "Func called." << std::endl;
}
~X()
{
std::cout << "Destroyed." << std::endl;
}
};
class Y
{
X* x = nullptr;
public:
void CallFunc()
{
//if (x == nullptr)
// x = new X;
static bool CodeToBeExecutedOnlyOnce =
[this]() { x = new X; return true; } ();
x->Func();
}
~Y()
{
delete x;
}
};
int main()
{
Y y;
y.CallFunc();
y.CallFunc();
y.CallFunc();
y.CallFunc();
y.CallFunc();
}
Вывод:
Constructed.
Func called.
Func called.
Func called.
Func called.
Func called.
Destroyed.
Мне понравилась идея, потому что таким образом мне не нужно каждый раз проверять, что произойдет только один раз. Но потом задумался, действительно ли это улучшает производительность? Как переменные функции stati c оцениваются только один раз? Например, если бы это была переменная-член класса stati c, это бы имело смысл. Возможно переменные stati c инициализируются во время компиляции (поправьте меня, если я ошибаюсь). Но для функции stati c переменные? Как они инициализируются только один раз при вызове функции? Происходит ли проверка каждый раз, когда кто-то вызывает функцию, чтобы проверить, была ли переменная инициализирована или нет? Есть ли лучший или более чистый способ достижения того же результата? Является ли этот способ выполнения части кода только один раз потокобезопасным? В ответе указано, что для обеспечения многопоточности компилятор должен поддерживать поточно-ориентированную инициализацию stati c. Означает ли это, что в некоторых компиляторах это может быть небезопасно? Добавляет ли поддержка поточно-ориентированной инициализации некоторое снижение производительности?
Подводя итог, я задаю следующие вопросы:
Как переменные функции stati c инициализируются только один раз, когда эта функция называется?
Улучшает ли это решение каким-либо образом производительность? Или функция проверяет каждый раз, инициализируется ли переменная stati c или нет?
Есть ли более чистый способ выполнить кусок кода только один раз? Может быть, без этого обходного пути объявления переменной типа stati c bool?
Является ли этот способ поточно-ориентированным? Если два потока вызывают функцию одновременно, будет ли переменная stati c инициализироваться дважды? И увеличивает ли потокобезопасность некоторые издержки производительности?
РЕДАКТИРОВАТЬ: только что понял, этот метод вызова кода только один раз не будет работать, так как инициализация только выполняется один раз (поскольку это переменная stati c), и только первый объект, для которого будет создан экземпляр, будет запускать этот кусок кода.