您当前的位置:首页 > 计算机 > 编程开发 > Other

如何保证函数只被调用一次

时间:04-02来源:作者:点击数:

经常会有一些函数全局只需要调用一次,如WSAStartup等,一般这种都会在程序入口处统一单独调用,但也容易忘记,封装在其他地方难免多次初始化,在C++中可以考虑采用一些技巧来实现。

静态flag判断

采用静态变量进行全局控制,大概实现如下

static bool flag = true;
if(flag)
{
    foo();
    flag = false;
}

非常简单完美的实现了只调用一次的功能,但是总感觉是比较low,不符合气质。

静态赋值实现

假设函数返回某种类型,比如int

static int dummy = foo();

简洁高效,利用静态成员初始化一次的特性实现,比前面的方法看起来高大上多了。但是,如果函数返回void怎么办,总不能继续套用上面的方法,毕竟我们知道void不是个类型,没理解的再去重温下。

也许可以考虑这么封装一下,比如

bool dummyfunc(void){return true;}
static bool dummy = dummyfunc(foo()); //!不能生效

但是事实上这个也还是不行的,void不能传值赋值,也就不能这么做。

幸亏C/C++还有个逗号运算符,逗号表达式会这个计算每个子表达式,并返回最后一个子表达式的值。于是乎,可以用逗号封装实现,也是简洁高效。

static bool dummy = (foo(), true);

这种办法更加精简了,调整顺序,可以解决返回值不同的问题。

call_once实现

C++11有call_once实现,可以实现只调用一次。

static std::once_flag oc;  
std::call_once(oc, foo);

如果关心返回值,可以直接使用lambda表达式封装,毕竟都使用C++11了。另外once_flag采用静态只是为了保证多次调用是同一个flag,完全可以采用类成员等方式。

bool result = false;
std::call_once(this->oc, [=, &result]() { result = this->foo(); });

总的来说,上面几种方式,多线程并发情况下应该只有静态赋值及call_once可以保证功能没问题。建议采用逗号方式,毕竟通用,不需要特殊的编译器要求。当然我们也可以采用原子及锁等方式实现个。

方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门