如何确保只调用一次函数

Bai*_*ang 26 c++

假设我有一个名为caller的函数,它将调用一个名为callee的函数:

void caller()
{
    callee();
}  
Run Code Online (Sandbox Code Playgroud)

现在可以在应用程序中多次调用调用者,并且您希望确保只调用一次调用者.(一种懒惰的初始化),你可以使用一个标志来实现它:

void caller()
{
    static bool bFirst = true;
    if(bFirst)
    {
        callee();
        bFirst = false;
    }
}
Run Code Online (Sandbox Code Playgroud)

我的意见是它需要更多的代码,并且每次调用函数调用者都需要再检查一次.
对我来说更好的解决方案如下:(假设被调用者返回int)

void caller()
{
    static int ret = callee();
}  
Run Code Online (Sandbox Code Playgroud)

但如果callee返回void,则无法处理此情况,我的解决方案是使用逗号表达式:

void caller()
{
    static int ret = (callee(), 1);
}  
Run Code Online (Sandbox Code Playgroud)

但问题在于,逗号表达式并不常用,人们在看到这行代码时可能会感到困惑,从而导致维护问题.

你有什么好主意确保只调用一次函数吗?

wim*_*ica 19

你可以用这个:

void caller()
{
    static class Once { public: Once(){callee();}} Once_;
}
Run Code Online (Sandbox Code Playgroud)

  • @StackedCrooked:在C++ 03中不是线程安全的,在C++ 0x中是线程安全的. (5认同)

ron*_*nag 12

线程安全:

    static boost::once_flag flag = BOOST_ONCE_INIT;
    boost::call_once([]{callee();}, flag);  
Run Code Online (Sandbox Code Playgroud)

  • 不,它可以在函数内部,因为它是静态的. (2认同)
  • 只是想补充一点,从 c++11 开始,std::call_once 现在可用,并且应该使用它来代替 boost::call_once。使用上唯一的区别是该标志不需要初始化(只是默认构造) (2认同)

nos*_*nos 7

您可以通过函数指针隐藏该函数.

static void real_function()
{
  //do stuff

  function = noop_function;
}


static void noop_function()
{

}

int (*function)(void) = real_function;
Run Code Online (Sandbox Code Playgroud)

呼叫者只是打电话给function谁第一次做这项工作,并且不对任何后续呼叫做任何事情.

  • @ArmenTsirunyan当然,在他们醒来并意识到它完全没问题之后,`static`很快就会在C++ 11最终确定之前被弃用. (3认同)