C++11与设计模式的交流
單例模式
針對多個(gè)參數(shù)的單例模式,使用變長類型的模版
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改進(jìn)觀察者模式:
通過被通知接口參數(shù)化和std::function來替代繼承。通過可變參數(shù)模版和完美轉(zhuǎn)發(fā)消除接口變換產(chǎn)生的影響。
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++改進(jìn)訪問者模式
訪問者模式表示一個(gè)作用于某對象結(jié)構(gòu)中的各元素的操作,可用于不改變各元素的類的其前提下定義作用于這些元素的操作。
缺點(diǎn)是如果改變對象的結(jié)構(gòu)類需要重新定義對所有訪問者的接口,這個(gè)需要付出很大的代價(jià)。
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;會自動(dòng)生成stA和stBde visit方法:
struct Visitor<stA,stB>
{
? ?virtual void Visit(const? stA &)=0;
? ?virtual void Visit(const stB &)=0;
};
c++11改進(jìn)命令模式
命令模式
命令模式的作用是將請求封裝為一個(gè)對象,將請求的發(fā)起者和執(zhí)行者解耦,支持對請求的排隊(duì),撤銷和重做。
c++11解決了命令類爆炸的問題,定義通用的泛化的命令類,這個(gè)命令類可以泛化所有的命令。
#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 對象池
普通的對象池有兩個(gè)問題:
1)對象用完后,需要手動(dòng)回收
2)不支持參數(shù)不同的構(gòu)造函數(shù)
通過c++11可以解決這兩個(gè)問題:
1)通過自動(dòng)回收用完的對象來解決,用智能指針,傳遞指定的刪除器
2)通過可變參數(shù)模版
#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;
};
?
?
?
總結(jié)
以上是生活随笔為你收集整理的C++11与设计模式的交流的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: c++11 chrono
- 下一篇: s3c2440移植MQTT