单例模式
针对多个参数的单例模式,使用变长类型的模版
template<T>
class Singleton{
public:
template<typename ... Args>
static T* Instance(Args... args){
if(m_pInstance==nullptr){
m_pInstance=new T();
}
return m_pinstance;
}
}
c++11改进观察者模式:
通过被通知接口参数化和std::function来替代继承。通过可变参数模版和完美转发消除接口变换产生的影响。
template<typename F>
int Assign(F&& f){
int k=m_obserId++;
m_connections.emplace(k,std::forward<F>(f));
return k;
}
template<typename ... Typs>
void Notify(Args... args){
for(auto & it:m_connections)
it.sencod(std::forward<Args>(args)...);
}
c++改进访问者模式
访问者模式表示一个作用于某对象结构中的各元素的操作,可用于不改变各元素的类的其前提下定义作用于这些元素的操作。
缺点是如果改变对象的结构类需要重新定义对所有访问者的接口,这个需要付出很大的代价。
template<typename ... Args>
struct Visitor.
template<typename T, typename ... Types>
struct Visitor<T, Types...>:Visitor<Types..>
{
using Visitor<Types...>::Visit;
virtual void Visit(const T&)=0;
}
tempalte<typename T>
struct Visitor<T>
{
virtual void Visit(const T&)=0;
};
struct PrintVisitor:Base::MytVisitor{
void Visit(const stA& a){}
void Visit(const stB& b){}
}
struct Base{
typedef Visitor<stA,stB> MyVisitor;
virtual void Accept(MyVisitor&)=0;
}
struct stA: Base{
doble val;
void Accept(Base::MytVisitor& v)
{
v.Visit(*this);
}
}
typedef Visitor<stA,stB> MytVisitor;会自动生成stA和stBde visit方法:
struct Visitor<stA,stB>
{
virtual void Visit(const stA &)=0;
virtual void Visit(const stB &)=0;
};
c++11改进命令模式
命令模式
命令模式的作用是将请求封装为一个对象,将请求的发起者和执行者解耦,支持对请求的排队,撤销和重做。
c++11解决了命令类爆炸的问题,定义通用的泛化的命令类,这个命令类可以泛化所有的命令。
#include<functional>
#include<type_traits>
template<typename R=Void>
struct Command{
private:
std::function<R()> m_f;
public:
template< class F, class ... Args, class =typename std::enable_if<!std::is_member_fucntion_pointer<F>::value>::type>
void wrap(F && f, Args && ... args){
m_f=[&]{return f(args...));
}
template<class R, class C, class... DArgs, class P, class ... Args>
void wrap(R(C::*f) const, P && p, Args && ... args){
m_f=[&,f]{return (*p.*f)(args...)};
}
c++11 对象池
普通的对象池有两个问题:
1)对象用完后,需要手动回收
2)不支持参数不同的构造函数
通过c++11可以解决这两个问题:
1)通过自动回收用完的对象来解决,用智能指针,传递指定的删除器
2)通过可变参数模版
#pragma once
#include<memory>
#include<exception>
#include<string>
#include<map>
const int MaxObjctNum = 10;
template<typename T>
class objectPool {
template<typename ... Args>
using Construct = std::function<std::shared_ptr<T>(Args...)>;
public:
template<typename ... Args>
void Init(size_t num, Args... args) {
if (num<0 || num>MaxObjctNum) {
throw std::logic_error("obj num out of range");
}
auto constructName = typeid(Construct<Args...>).name();
for (size_t i = 0; i < num; i++) {
m_object_map.emplace(constructName, std::shared_ptr<T>(new T(std::forward<Args>(args)...), [this, constructName](T* p)
{
m_object_map.emplace(std::move(constructName), std::shared_ptr<T>(p));
}));
}
}
template<typename ... Args>
std::shared_ptr<T> Get() {
std::string constructName = typeid(Construct<Args...>).name();
auto range = m_object_map.equal_range(constructName);
for (auto it = range.first; it != range.second; ++it) {
auto ptr = it->second;
m_object_map.erase(it);
return ptr;
}
return nullptr;
}
private:
std::multimap<std::string, std::shared_ptr<T>> m_object_map;
};