C++11与设计模式的交流

单例模式

针对多个参数的单例模式,使用变长类型的模版

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;
};
 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值