Suppose I have a function named caller, which will call a function named callee:
假设我有一个名为caller的函数,它将调用一个名为callee的函数:
void caller()
{
callee();
}
Now caller might be called many times in the application, and you want to make sure callee is only called once. (kind of lazy initialization), you could implement it use a flag:
现在调用者可能在应用程序中被多次调用,并且您希望确保只调用一次被调用者。 (一种懒惰的初始化),你可以使用一个标志来实现它:
void caller()
{
static bool bFirst = true;
if(bFirst)
{
callee();
bFirst = false;
}
}
My opinion for this is it needs more code, and it needs one more check in every call of function caller.
A better solution to me is as follow: (suppose callee returns int)
我的意见是它需要更多的代码,并且每次调用函数调用者都需要再检查一次。对我来说更好的解决方案如下:(假设被调用者返回int)
void caller()
{
static int ret = callee();
}
But this can't handle the case if callee returns void, my solution is using the comma expression:
但如果callee返回void,则无法处理此情况,我的解决方案是使用逗号表达式:
void caller()
{
static int ret = (callee(), 1);
}
But the problem with this is that comma expression is not popular used and people may get confused when see this line of code, thus cause problems for maintainance.
但问题在于,逗号表达式并不常用,人们在看到这行代码时可能会感到困惑,从而导致维护问题。
Do you have any good idea to make sure a function is only called once?
你有什么好主意确保只调用一次函数吗?
5 个解决方案
#1
12
Thread-safe:
线程安全:
static boost::once_flag flag = BOOST_ONCE_INIT;
boost::call_once([]{callee();}, flag);
#2
19
You could use this:
你可以用这个:
void caller()
{
static class Once { public: Once(){callee();}} Once_;
}
#3
7
You could hide the function through a function pointer.
您可以通过函数指针隐藏该函数。
static void real_function()
{
//do stuff
function = noop_function;
}
static void noop_function()
{
}
int (*function)(void) = real_function;
Callers just call the function
which will do the work the first time, and do nothing on any subsequent calls.
呼叫者只是调用将在第一次执行工作的功能,并且不会对任何后续呼叫执行任何操作。
#4
2
Your first variant with a boolean flag bFirst
is nothing else that an explict manual implementatuion of what the compiler will do for you implictly in your other variants.
你的第一个带有布尔标志bFirst的变体就是编译器在你的其他变种中隐含的一个手段实现。
In other words, in a typical implementation in all of the variants you pesented so far there will be an additional check for a boolean flag in the generated machine code. The perfromance of all these variants will be the same (if that's your concern). The extra code in the first variant might look less elegant, but that doesn't seem to be a big deal to me. (Wrap it.)
换句话说,在您所提出的所有变体的典型实现中,将在生成的机器代码中额外检查布尔标志。所有这些变体的性能都是相同的(如果这是您的关注)。第一个版本中的额外代码可能看起来不那么优雅,但这对我来说似乎并不重要。 (包裹它。)
Anyway, what you have as your first variant is basically how it is normally done (until you start dealing with such issues as multithreading etc.)
无论如何,你作为你的第一个变体基本上是如何正常完成的(直到你开始处理多线程等问题)
#5
0
Inspired by some people, I think just use a macro to wrap comma expression would also make the intention clear:
受到一些人的启发,我认为使用宏来包装逗号表达式也会使意图明确:
#define CALL_ONCE(func) do {static bool dummy = (func, true);} while(0)
#1
12
Thread-safe:
线程安全:
static boost::once_flag flag = BOOST_ONCE_INIT;
boost::call_once([]{callee();}, flag);
#2
19
You could use this:
你可以用这个:
void caller()
{
static class Once { public: Once(){callee();}} Once_;
}
#3
7
You could hide the function through a function pointer.
您可以通过函数指针隐藏该函数。
static void real_function()
{
//do stuff
function = noop_function;
}
static void noop_function()
{
}
int (*function)(void) = real_function;
Callers just call the function
which will do the work the first time, and do nothing on any subsequent calls.
呼叫者只是调用将在第一次执行工作的功能,并且不会对任何后续呼叫执行任何操作。
#4
2
Your first variant with a boolean flag bFirst
is nothing else that an explict manual implementatuion of what the compiler will do for you implictly in your other variants.
你的第一个带有布尔标志bFirst的变体就是编译器在你的其他变种中隐含的一个手段实现。
In other words, in a typical implementation in all of the variants you pesented so far there will be an additional check for a boolean flag in the generated machine code. The perfromance of all these variants will be the same (if that's your concern). The extra code in the first variant might look less elegant, but that doesn't seem to be a big deal to me. (Wrap it.)
换句话说,在您所提出的所有变体的典型实现中,将在生成的机器代码中额外检查布尔标志。所有这些变体的性能都是相同的(如果这是您的关注)。第一个版本中的额外代码可能看起来不那么优雅,但这对我来说似乎并不重要。 (包裹它。)
Anyway, what you have as your first variant is basically how it is normally done (until you start dealing with such issues as multithreading etc.)
无论如何,你作为你的第一个变体基本上是如何正常完成的(直到你开始处理多线程等问题)
#5
0
Inspired by some people, I think just use a macro to wrap comma expression would also make the intention clear:
受到一些人的启发,我认为使用宏来包装逗号表达式也会使意图明确:
#define CALL_ONCE(func) do {static bool dummy = (func, true);} while(0)