参考网址
https://github.com/ZLMediaKit/ZLMediaKit/wiki/%E4%BB%A3%E7%A0%81%E7%AF%87%E4%B9%8BonceToken
onceToken是一个函数容器,{}这个里面写函数的代码
1、作为全局变量用,在程序加载时执行特定代码
代码只执行1次,定义成全局变量时
#include <iostream>
#include "onceToken.h"
using namespace std;
//using namespace toolkit;
int i = 1;
toolkit::onceToken token([](){
//是一个lambda函数,程序加载时只被执行一次
//i=4;
for(int j=0; j<3;j++)
i++;
});
int main(int argc, char *argv[])
{
cout << "Hello World!" << endl;
cout << "i=" <<i<< endl;
return 0;
}
输出结果
2.作为static变量,确保代码只执行一次
#include <iostream>
#include "onceToken.h"
using namespace std;
//using namespace toolkit;
int i = 1;
int main(int argc, char *argv[])
{
cout << "Hello World!" << endl;
static toolkit::onceToken token([](){
//是一个lambda函数,只被执行一次
i=5;
});
cout << "i=" <<i<< endl; //这里输出结果是5
return 0;
}
输出结果
3.作为局部变量,确保函数退出前做一些清理工作,例如释放锁:
template<typename ...ArgsType>
bool emitEvent(const string &strEvent,ArgsType &&...args){
onceToken token(
[&] {//这个函数是onConstructed,理解成构造函数
//上锁,记录锁定线程id
_mtxListener.lock();
if(_lock_depth++ == 0){
_lock_thread = this_thread::get_id();
}
},
[&]() {//这个函数是onDestructed,理解成析构函数
//释放锁,取消锁定线程id
if(--_lock_depth == 0){
_lock_thread = thread::id();
if(_map_moved){
//还原_mapListener
_map_moved = false;
_mapListener = std::move(_mapListenerTemp);
}
}
_mtxListener.unlock();
});
//后续代码省略
}
类 onceToken的源码 解读
#ifndef UTIL_ONCETOKEN_H_
#define UTIL_ONCETOKEN_H_
#include <functional>
#include <type_traits>
using namespace std;
namespace toolkit {
class onceToken {
public:
typedef function<void(void)> task;
template<typename FUNC>
//onConstructed是起始函数,onDestructed是结束函数默认空指针
//自定义了构造函数,用delete禁止生成默认构造函数
onceToken(const FUNC &onConstructed, function<void(void)> onDestructed = nullptr) {
onConstructed();
_onDestructed = std::move(onDestructed);
}
onceToken(nullptr_t, function<void(void)> onDestructed = nullptr) {
_onDestructed = std::move(onDestructed);
}
~onceToken() {
if (_onDestructed) {
_onDestructed();
}
}
private:
onceToken() = delete; //禁止生成默认构造函数
onceToken(const onceToken &) = delete; //禁止生成默认拷贝构造函数
onceToken(onceToken &&) = delete; //禁止生成默认移动构造函数
onceToken &operator=(const onceToken &) = delete; //禁止生成默认赋值函数
onceToken &operator=(onceToken &&) = delete; //禁止生成移动拷贝函数
private:
task _onDestructed;
};
} /* namespace toolkit */
#endif /* UTIL_ONCETOKEN_H_ */