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

 

一个函数caller会在其内部调用另外一个函数callee,现在的情况是,caller可能会在多个地方被多次调用,而你希望callee只在第一次被调用时被调用一次。一般情况下,callee会是一个对环境或者资源的初始化工作。

或许,从代码结构的角度来讲,你第一个想到的是把callee从caller中拿出来,放到某个合适的地方做初始化,这是个不错的方法,但相信我,在有些时候这并不是个有效的办法:你可能无法找个那个“合适的地方”,你也可能找到了但因此而失去lazy initialization的好处~~~。

这里,我只想对这个问题找个好点的方法。

第一个方法很简单,就是用个静态的flag来判断:


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

这个可以非常完美的工作,但是代码感觉多了点,不够简洁。

而且每个后续调用都要有个取反和判断操作,这对调用频繁的操作的性能是有影响的。另外,即使影响不大,从程序员感受的角度来看,你也不希望有多余的判断~~~

哦,取反可以去掉:


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

但是,判断还是存在。

【编辑:SO上讨论中有人指出,即使使用static变量,其实也会有一个判断操作,这一点说出了问题的根本,所以关于效率的论述是不必要的】

当然,我们还有第二种更简洁的方法,假设callee的返回类型时int:

static int dummy = callee(); // 1)

完了,利用静态变量只初始化一次的特点就可以实现,简洁,而且高效。

但是,这里有个问题:如果callee的返回类型时void,那怎么办?你不能:

static void dummy = callee(); static int dummy = (int)callee(); static int dummy = reinterpret_cast<int>(callee());

因为void其实不是个类型,而是没有类型。

即使你觉得自己很聪明,想出了下面这种方式:

bool dummyfunc(void){return true;} static bool dummy = dummyfunc(callee());

那也是不灵光的,不要以为callee返回void,把返回的void传给dummyfunc的参数就可以了,因为void根本就不是个类型,根本没有赋值,传值这个概念~~~

幸亏C++中还有个叫逗号表达式的东西,说实话,C++用了7年多,这是我第一次发现逗号表达式这么可爱:

逗号表达式会这个计算每个子表达式,并返回最后一个子表达式的值

于是,就有了这个解决方案:

static bool dummy = (callee(), true); // 2)

也是同样的简洁、高效。

看来,直接用静态变量初始化的方法是可以达到这个目的,而且会更好。

附:

我相信还会有其他方法来处理callee返回void的情况的,如果你知道,请不吝赐教!

来源:http://www.cnblogs.com/baiyanhuang/archive/2010/11/13/1876677.html

VC++函数只被调用一次的更多相关文章

  1. vc MFC 通过IDispatch调用默认成员函数

    CComPtr<IDispatch> spDisp(IDispatch *); if(!spDisp) return; DISPPARAMS dispParam={0}; //没有参数 V ...

  2. VS2013 VC++的.cpp文件调用CUDA的.cu文件中的函数

    CUDA 8.0在函数的调用中方便的让人感动.以下是从网上学到的VC++的.cpp文件调用CUDA的.cu文件中的函数方法,和一般的VC++函数调用的方法基本没差别. 使用的CUDA版本为CUDA 8 ...

  3. VC++线程函数内怎么调用外部函数

    VC++线程函数内怎么调用外部函数 1.把外部函数做成静态函数,就可以直接调用了.2.把外部函数所在的对象通过线程函数参数传到线程里面来,这样线程里可以使用此对象及其函数了.

  4. [Effective JavaScript 笔记]第17条:间接调用eval函数优于直接调用

    eval函数不仅仅是一个函数.大多数函数只访问定义它们所在的作用域,而不能访问除此之外的作用域(词法作用域).eval函数具有访问调用它时的整个作用域的能力.编译器编写者首次设法优化js时,eval函 ...

  5. JavaScript函数的各种调用模式

    函数是JavaScript世界里的第一公民,换句话来说,就是我们如果可以精通JavaScript函数的使用,那么对JavaScript的运用可以更游刃有余了.熟悉JavaScript的人应该都知道,同 ...

  6. python中函数的定义,调用,全局变量,局部变量,函数的嵌套使用-初级篇

    函数的基本概述 在学习函数之前,一直遵循:面向过程编程,即:根据业务逻辑从上到下实现功能,可以思考一下如果有某个功能的代码是在多个地方使用的是否可以只写一次?此时的代码该如何定义.先观察以下的案例: ...

  7. linux中 probe函数的何时调用的?

    点击打开链接 linux中 probe函数何时调用的 所以的驱动教程上都说:只有设备和驱动的名字匹配,BUS就会调用驱动的probe函数,但是有时我们要看看probe函数里面到底做了什么,还有传递给p ...

  8. ES6躬行记(15)——箭头函数和尾调用优化

    一.箭头函数 箭头函数(Arrow Function)是ES6提供的一个很实用的新功能,与普通函数相比,不但在语法上更为简洁,而且在使用时也有更多注意点,下面列出了其中的三点: (1)由于不能作为构造 ...

  9. day11函数的参数,函数对象 - 函数名,函数的嵌套调用

    复习 # 什么是函数:具体特定功能的代码块 - 特定功能代码块作为一个整体,并给该整体命名,就是函数 # 函数的优点: # 1.减少代码的冗余 # 2.结构清晰,可读性强 # 3.具有复用性,开发效率 ...

随机推荐

  1. Tutorial: Synchronizing State with Mutexes in Go

    go语言中用mutex实现状态同步. 原文:https://kylewbanks.com/blog/tutorial-synchronizing-state-with-mutexes-golang - ...

  2. 贪吃蛇 c++ ncurses

    近期学ncurses.用贪吃蛇训练下 思路:不构造链表.蛇头向前进方向打点,蛇尾逐点消失,形成移动. 须要记录蛇头方向,蛇尾方向.并用list仿造队列,增加拐点信息(空间比链表每一个结点开辟空间节省非 ...

  3. Objective-C之成魔之路【8-訪问成员变量和属性】

    郝萌主倾心贡献,尊重作者的劳动成果.请勿转载. 假设文章对您有所帮助,欢迎给作者捐赠,支持郝萌主,捐赠数额任意,重在心意^_^ 我要捐赠: 点击捐赠 Cocos2d-X源代码下载:点我传送 訪问成员变 ...

  4. ie 代理设置中地址和端口置灰的解决办法

    @echo offecho 代理设置reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings&quo ...

  5. 为何被主流抛弃-江西IDC机房价格为何居高不下缺少竞争力-2014年5月江西IDC排行榜

     经常有人问江西IDC排行榜,为什么江西市场缺乏活力. 榜单调研者们有时仅仅能表示无解和无奈. 在IDC领域,其实已经形成了一二三线的城市之分. 一线城市是以上海.北京.深圳为代表的拥有最早国际宽 ...

  6. C中多线程开发

    1 引言  线程(thread)技术早在60年代就被提出,但真正应用多线程到操作系统中去,是在80年代中期.solaris是这方面的佼佼者.传统的 Unix也支持线程的概念,可是在一个进程(proce ...

  7. php(cli模式)执行文件传递参数

    php -f index.php hello test 2314 shell命令执行php文件不像http那样通过GET方式传参 同样php文件获取的时候也不能用$_GET方法了 而是通过$argv[ ...

  8. Cannot change version of project facet Dynamic Web Module to 3.1 (Eclipse Maven唯一解决方式)

    If you want to use version 3.1 you need to use the following schema: http://xmlns.jcp.org/xml/ns/jav ...

  9. ios7 UIBarButtonItem 默认蓝色

    [self.navigationItem setLeftBarButtonItem:leftButton]; 这样设置在ios7上button默认是蓝色 解决方法: leftButton.tintCo ...

  10. [计算机故障]excel无法存盘,总是自动重启恢复

    同事的excel文档,无法保存.总是提示什么要发送错误报告.错误报告中的错误信息包含event type:BXE.这个文件大小约1M多.工作簿中包含表大约有30张,表名称为中文.我去看了看,其他电子表 ...