lambd表达式
1.捕获列表。在C++规范中也称为Lambda导入器, 捕获列表总是出现在Lambda函数的开始处。实际上,[]是Lambda引出符。编译器根据该引出符判断接下来的代码是否是Lambda函数,捕获列表能够捕捉上下文中的变量以供Lambda函数使用。
2.参数列表。与普通函数的参数列表一致。如果不需要参数传递,则可以连同括号“()”一起省略。
3.可变规格。mutable修饰符, 默认情况下Lambda函数总是一个const函数,mutable可以取消其常量性。在使用该修饰符时,参数列表不可省略(即使参数为空)。
4. 异常说明。用于Lamdba表达式内部函数抛出异常。
5. 返回类型。 追踪返回类型形式声明函数的返回类型。我们可以在不需要返回值的时候也可以连同符号”->”一起省略。此外,在返回类型明确的情况下,也可以省略该部分,让编译器对返回类型进行推导。
lambda函数体。内容与普通函数一样,不过除了可以使用参数之外,还可以使用所有捕获的变量。
捕获列表
[]表示不捕获任何变量
[var]表示值传递方式捕获变量var
[=]表示值传递方式捕获所有父作用域的变量(包括this)
[&var]表示引用传递捕捉变量var
[&]表示引用传递方式捕捉所有父作用域的变量(包括this)
[this]表示值传递方式捕捉当前的this指针
[=, &] 拷贝与引用混合
[=, &a, &b]表示以引用传递的方式捕捉变量a和b,以值传递方式捕捉其它所有变量
[&, a, this]表示以值传递的方式捕捉变量a和this,引用传递方式捕捉其它所有变量。
不过值得注意的是,捕捉列表不允许变量重复传递。下面一些例子就是典型的重复,会导致编译时期的错误。例如:
[=,a]这里已经以值传递方式捕捉了所有变量,但是重复捕捉a了,会报错的;
[&,&this]这里&已经以引用传递方式捕捉了所有变量,再捕捉this也是一种重复。
第一代对象池
#ifndef OBJECTPOOL1_HPP
#define OBJECTPOOL1_HPP
#include<list>
#include<memory>
#include<iostream>
using namespace std;
template<class TObject>
class ObjectPool
{
private:
std::list<TObject *> idlepool;
public:
ObjectPool() {}
~ObjectPool()
{
clear();
}
ObjectPool(const ObjectPool &) = delete; //C++11
ObjectPool & operator=(const ObjectPool &) = delete;
public:
std::shared_ptr<TObject> acquire()
{
if(idlepool.empty())
{
return std::shared_ptr<TObject> (new TObject(),
[&](TObject *p)->void
{
idlepool.push_back(p);
});
//共享指针管理new TObject(),在引用计数等于0调用删除器的时候,
//new TObject()就会把自己的地址给删除器,也就是p指向了这个new TObject()
}
else
{
auto ptr = idlepool.front();
idlepool.pop_front();
return std::shared_ptr<TObject> (ptr,
[&](TObject *p)->void
{
idlepool.push_back(p);
});
}
}
size_t getsize() const
{
return idlepool.size();
}
void clear()
{
for(auto &pobj : idlepool)
{
delete pobj;
pobj = nullptr;
}
idlepool.clear();
}
};
//这里结构是队列,有前驱域,后继域,数据域,其中数据域指向智能指针的地址,
//所以在删除的时候先删除智能指针并置空,再讲队列这个数据结构删掉
#endif
第二代对象池(添加了完美转发和可变模板参数)
#ifndef OBJECTPOOL2_HPP
#define OBJECTPOOL2_HPP
#include <list>
#include <memory>
#include <iostream>
using namespace std;
template <class TObject>
class ObjectPool
{
private:
std::list<TObject *> idlepool;
public:
ObjectPool() {}
~ObjectPool()
{
clear();
}
ObjectPool(const ObjectPool &) = delete; // C++11
ObjectPool &operator=(const ObjectPool &) = delete;
public:
//是C++中的可变参数模板的语法表示。
//在C++11之后,引入了可变参数模板的特性,使得可以定义接受任意数量、任意类型的模板参数的函数或类模板。
template <class... Args>
std::shared_ptr<TObject> acquire(Args &&...args)
//Args:是模板参数包的名称,表示函数接受的模板参数的类型。
//&&:是右值引用的标记,用于实现完美转发的功能。
//通过使用&&,acquire函数可以在保留传入参数的引用性质的同时,将其转发给其他函数。
{
if (idlepool.empty())
{
return std::shared_ptr<TObject>(
new TObject(std::forward<Args>(args)...),
[&](TObject *p) -> void
{
idlepool.push_back(p);
});
}
else
{
auto ptr = idlepool.front();
idlepool.pop_front();
return std::shared_ptr<TObject>(
ptr,
[&](TObject *p) -> void
{
idlepool.push_back(p);
});
}
}
size_t getsize() const
{
return idlepool.size();
}
void clear()
{
for (auto &pobj : idlepool)
{
delete pobj;
pobj = nullptr;
}
idlepool.clear();
}
};
#endif
第三代对象池(单独封装了删除器,对对象池个数进行限制)
#ifndef OBJECTPOOL3_HPP
#define OBJECTPOOL3_HPP
#include <list>
#include <memory>
#include <iostream>
using namespace std;
template <class TObject>
class ObjectPool
{
private:
std::list<TObject *> idlepool;
size_t maxTotal; // 8 maxtotal(最大对象个数),
size_t maxIdle; // 6,maxidle(最大空闲对象个数,就是在池子里的个数)
size_t totalObject = 0;//totalObject(现有对象个数)
void release(TObject *ptr)
{
if(idlepool.size() < maxIdle)//对象池允许放入的对象个数
{
idlepool.push_back(ptr);
}
else
{
--totalObject;
delete ptr;
cout<<"空闲池已满, 直接删除object"<<endl;
}
}
public:
ObjectPool(size_t maxtotal = 8, size_t maxidle = 6)
:maxTotal(maxtotal),maxIdle(maxidle)
{}
~ObjectPool()
{
clear();
}
ObjectPool(const ObjectPool &) = delete; // C++11
ObjectPool &operator=(const ObjectPool &) = delete;
public:
template <class... Args>
std::shared_ptr<TObject> acquire(Args &&...args)
{
if (totalObject < maxTotal && idlepool.empty())
//如果对象池为空并且 现有对象个数 < 最大对象个数
{
++totalObject;
return std::shared_ptr<TObject>(
new TObject(std::forward<Args>(args)...),
[&](TObject *p) -> void
{
release(p);
});
}
else if(!idlepool.empty())
{
auto ptr = idlepool.front();
idlepool.pop_front();
return std::shared_ptr<TObject>(
ptr,
[&](TObject *p) -> void
{
release(p);
});
}
//已达到最大对象个数,或者对象池为空并且无法创建新资源
return std::shared_ptr<TObject>(nullptr);
}
size_t getIdleObjectNum() const
{
return idlepool.size();
}
size_t getTotalObjectNum() const
{
return totalObject;
}
size_t getActivateObejctNum() const
{
return totalObject - idlepool.size();
}
void clear()
{
for (auto &pobj : idlepool)
{
delete pobj;
pobj = nullptr;
}
idlepool.clear();
}
};
#endif
第四版对象池(对于多线程加入了互斥锁,条件变量,等待时间)
#ifndef OBJECTPOOL4_HPP
#define OBJECTPOOL4_HPP
#include <list>
#include <memory>
#include <iostream>
#include <mutex>
#include <condition_variable>
using namespace std;
template <class TObject>
class ObjectPool
{
private:
std::list<TObject *> idlepool;
size_t maxTotal; // 8 maxtotal(最大对象个数),
size_t maxIdle; // 6 maxidle(最大空闲对象个数,
size_t totalObject = 0;//totalObject(现有对象个数)
size_t maxWaitTime = 2; ///10;
std::mutex m_mutex;
std::condition_variable m_cv;
void release(TObject *ptr)
{
std::unique_lock<std::mutex> lock(m_mutex);
if(idlepool.size() < maxIdle)
{
idlepool.push_back(ptr);
}
else
{
--totalObject;
delete ptr;
cout<<"空闲池已满, 直接删除object"<<endl;
}
m_cv.notify_all();
}
public:
ObjectPool(size_t maxtotal = 8, size_t maxidle = 6)
:maxTotal(maxtotal),maxIdle(maxidle)
{}
~ObjectPool()
{
clear();
}
ObjectPool(const ObjectPool &) = delete; // C++11
ObjectPool &operator=(const ObjectPool &) = delete;
public:
template <class... Args>
std::shared_ptr<TObject> acquire(Args &&...args)
{
std::unique_lock<std::mutex> lock(m_mutex);
while(idlepool.empty() && totalObject >= maxTotal)
{
// m_cv.wait(lock);
//自己设置等待时间
if(std::cv_status::timeout ==
m_cv.wait_for(lock,std::chrono::milliseconds(maxWaitTime*1000)))
{
cout<<"timeout wait ... "<<endl;
return std::shared_ptr<TObject>(nullptr);
}
}
if (totalObject < maxTotal && idlepool.empty())
{
++totalObject;
return std::shared_ptr<TObject>(
new TObject(std::forward<Args>(args)...),
[&](TObject *p) -> void
{
release(p);
});
}
else if(!idlepool.empty())
{
auto ptr = idlepool.front();
idlepool.pop_front();
return std::shared_ptr<TObject>(
ptr,
[&](TObject *p) -> void
{
release(p);
});
}
//return std::shared_ptr<TObject>(nullptr);
}
size_t getIdleObjectNum() const
{
return idlepool.size();
}
size_t getTotalObjectNum() const
{
return totalObject;
}
size_t getActivateObejctNum() const
{
return totalObject - idlepool.size();
}
void clear()
{
for (auto &pobj : idlepool)
{
delete pobj;
pobj = nullptr;
}
idlepool.clear();
}
};
#endif