最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

通過c++11改進(jìn)我們的模式之改進(jìn)命令模式

 更新時(shí)間:2013年11月10日 10:13:59   作者:  
這篇我要講的是如何使用c++11改進(jìn)命令模式,感興趣的朋友可以看下

模式雖然精妙,卻難完美,比如觀察者模式中觀察者生命周期的問題;比如訪問者模式中循環(huán)依賴的問題等等;其它很多模式也存在這樣那樣的一些不足之處,如使用場(chǎng)景受限、實(shí)現(xiàn)復(fù)雜、不夠簡(jiǎn)潔、不夠通用等。但我覺得不足之處大都是可以采取一些手法去彌補(bǔ)去改進(jìn)的,比如用c++11的新特性來改進(jìn)。因此,便有了c++11改進(jìn)我們的模式這個(gè)系列。這次我要講的是如何使用c++11改進(jìn)命令模式。關(guān)于命令模式

  命令模式的作用是將請(qǐng)求封裝為一個(gè)對(duì)象,將請(qǐng)求的發(fā)起者和執(zhí)行者解耦,支持對(duì)請(qǐng)求排隊(duì)以及撤銷和重做。它的類圖如下:


  由于將請(qǐng)求都封裝成一個(gè)個(gè)命令對(duì)象了,使得我們可以集中處理或者延遲處理這些命令請(qǐng)求,而且不同的客戶對(duì)象可以共享這些命令,還可以控制請(qǐng)求的優(yōu)先級(jí)、排隊(duì)、支持請(qǐng)求命令撤銷和重做等等。命令模式的這些好處是顯而易見的,但是,在實(shí)際使用過程中它的問題也暴露出來了。隨著請(qǐng)求的增多,請(qǐng)求的封裝類--命令類也會(huì)越來越多,尤其是GUI應(yīng)用中,請(qǐng)求是非常多的。越來越多的命令類會(huì)導(dǎo)致類爆炸,難以管理。關(guān)于類爆炸這個(gè)問題,GOF很早就意識(shí)到了,他們提出了一個(gè)解決方法:對(duì)于簡(jiǎn)單的不能取消和不需要參數(shù)的命令,可以用一個(gè)命令類模板來參數(shù)化該命令的接收者,用接收者類型來參數(shù)化命令類,并維護(hù)一個(gè)接收者對(duì)象和一個(gè)動(dòng)作之間的綁定,而這一動(dòng)作是用指向同一個(gè)成員函數(shù)的指針存儲(chǔ)的。具體代碼是這樣的:
簡(jiǎn)單命令類的定義:

構(gòu)造器存儲(chǔ)接收者和對(duì)應(yīng)實(shí)例變量中行為。Execute操作實(shí)施接收者的這個(gè)動(dòng)作。

為創(chuàng)建一個(gè)調(diào)用MyClass類的一個(gè)實(shí)例上的Action行為的Command對(duì)象,僅需要如下代碼:

  通過一個(gè)泛型的簡(jiǎn)單命令類來避免不斷創(chuàng)建新的命令類,是一個(gè)不錯(cuò)的辦法,但是,這個(gè)辦法不完美,即它只能是簡(jiǎn)單的命令類,不能對(duì)復(fù)雜的,甚至所有的命令類泛化,這是它的缺陷,所以,它只是部分的解決了問題。我想我可以改進(jìn)這個(gè)辦法缺陷,完美的解決類爆炸的問題。在c++11之前我不知道有沒有人解決過這個(gè)問題,至少我沒看到過?,F(xiàn)在可以通過c++11來完美的解決這個(gè)問題了。

c++11改進(jìn)命令模式

  要完美的解決命令模式類爆炸問題的關(guān)鍵是如何定義個(gè)通用的泛化的命令類,這個(gè)命令類可以泛化所有的命令,而不是GOF提到的簡(jiǎn)單命令。我們?cè)倩剡^頭來看看GOF中那個(gè)簡(jiǎn)單的命令類的定義,它只是泛化了沒有參數(shù)和返回值的命令類,命令類內(nèi)部引用了一個(gè)接收者和接收者的函數(shù)指針,如果接收者的行為函數(shù)指針有參數(shù)就不能通用了,所以我們要解決的關(guān)鍵問題是如何讓命令類能接受所有的成員函數(shù)指針或者函數(shù)對(duì)象。
  有沒有一個(gè)能接受所有成員函數(shù)、普通函數(shù)和函數(shù)對(duì)象的類呢?有,在c++11中可以有,我上一篇博文中提到了一個(gè)萬能的函數(shù)包裝器,它可以接受所有的函數(shù)對(duì)象、fucntion和lamda表達(dá)式,它行不行呢?不行,因?yàn)樗€不夠完美,它還不能接受成員函數(shù)呢,所以它還不是真正的萬能的函數(shù)包裝器。我打算在它的基礎(chǔ)上再擴(kuò)展一下,讓它為一個(gè)真正的萬能的函數(shù)包裝器。

  接受function、函數(shù)對(duì)象、lamda和普通函數(shù)的包裝器:

復(fù)制代碼 代碼如下:

template< class F, class... Args, class = typename std::enable_if<!std::is_member_function_pointer<F>::value>::type>
void Wrap(F && f, Args && ... args)
{
return f(std::forward<Args>(args)...);
}

接受成員函數(shù)的包裝器:

復(fù)制代碼 代碼如下:

template<class R, class C, class... DArgs, class P, class... Args>
void Wrap(R(C::*f)(DArgs...), P && p, Args && ... args)
{
return (*p.*f)(std::forward<Args>(args)...);
}

  通過重載的Wrap讓它能接收成員函數(shù)。這樣一個(gè)真正意義上的萬能的函數(shù)包裝器就完成了?,F(xiàn)在再來看,它是如何應(yīng)用到命令模式中,完美的解決類爆炸的問題。

  一個(gè)通用的泛化的命令類:

復(fù)制代碼 代碼如下:

template<typename R=void>
struct CommCommand
{
private:
std::function < R()> m_f;

public:
template< class F, class... Args, class = typename std::enable_if<!std::is_member_function_pointer<F>::value>::type>
void Wrap(F && f, Args && ... args)
{
m_f = [&]{return f(std::forward<Args>(args)...); };
}

template<class R, class C, class... DArgs, class P, class... Args>
void Wrap(R(C::*f)(DArgs...) const, P && p, Args && ... args)
{
m_f = [&, f]{return (*p.*f)(std::forward<Args>(args)...); };
}

// non-const member function
template<class R, class C, class... DArgs, class P, class... Args>
void Wrap(R(C::*f)(DArgs...), P && p, Args && ... args)
{
m_f = [&, f]{return (*p.*f)(std::forward<Args>(args)...); };
}

R Excecute()
{
return m_f();
}
};

測(cè)試代碼:

復(fù)制代碼 代碼如下:

struct STA
{
int m_a;
int operator()(){ return m_a; }
int operator()(int n){ return m_a + n; }
int triple0(){ return m_a * 3; }
int triple(int a){ return m_a * 3 + a; }
int triple1() const { return m_a * 3; }
const int triple2(int a) const { return m_a * 3+a; }

void triple3(){ cout << "" <<endl; }
};

int add_one(int n)
{
return n + 1;
}

void TestWrap()
{

CommCommand<int> cmd;
// free function
cmd.Wrap(add_one, 0);

// lambda function
cmd.Wrap([](int n){return n + 1; }, 1);

// functor
cmd.Wrap(bloop);
cmd.Wrap(bloop, 4);

STA t = { 10 };
int x = 3;
// member function
cmd.Wrap(&STA::triple0, &t);
cmd.Wrap(&STA::triple, &t, x);
cmd.Wrap(&STA::triple, &t, 3);

cmd.Wrap(&STA::triple2, &t, 3);
auto r = cmd.Excecute();

CommCommand<> cmd1;
cmd1.Wrap(&Bloop::triple3, &t);
cmd1.Excecute();
}

我們?cè)谕ㄓ玫拿铑悆?nèi)部定義了一個(gè)萬能的函數(shù)包裝器,使得我們可以封裝所有的命令,增加新的請(qǐng)求都不需要重新定義命令了,完美的解決了命令類爆炸的問題。

相關(guān)文章

  • C++中l(wèi)ist的使用與模擬實(shí)現(xiàn)

    C++中l(wèi)ist的使用與模擬實(shí)現(xiàn)

    list相較于vector來說會(huì)顯得復(fù)雜,它的好處是在任意位置插入,刪除都是一個(gè)O(1)的時(shí)間復(fù)雜度,下面這篇文章主要給大家介紹了關(guān)于C++中l(wèi)ist的使用與模擬實(shí)現(xiàn)的相關(guān)資料,需要的朋友可以參考下
    2022-05-05
  • C++算法系列之日歷生成的算法代碼

    C++算法系列之日歷生成的算法代碼

    日歷算法首先要知道日歷的編排規(guī)則,也就是歷法。所謂歷法,指的就是推算年、月、日的時(shí)間長(zhǎng)度和它們之間的關(guān)系,指定時(shí)間序列的法則。
    2018-05-05
  • C++并查集親戚(Relations)算法實(shí)例

    C++并查集親戚(Relations)算法實(shí)例

    這篇文章主要介紹了C++并查集親戚(Relations)算法,實(shí)例分析了并查集親戚算法的原理與實(shí)現(xiàn)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-04-04
  • C語言中的強(qiáng)符號(hào)和弱符號(hào)介紹

    C語言中的強(qiáng)符號(hào)和弱符號(hào)介紹

    這篇文章主要介紹了C語言中的強(qiáng)符號(hào)和弱符號(hào)介紹,本文用多個(gè)實(shí)例來講解強(qiáng)符號(hào)和弱符號(hào),需要的朋友可以參考下
    2015-03-03
  • C 語言中enum枚舉的定義和使用小結(jié)

    C 語言中enum枚舉的定義和使用小結(jié)

    在 C 語言里,enum(枚舉)是一種用戶自定義的數(shù)據(jù)類型,它能夠讓你創(chuàng)建一組具名的整數(shù)常量,下面我會(huì)從定義、使用、特性等方面詳細(xì)介紹enum,感興趣的朋友一起看看吧
    2025-04-04
  • 用C語言實(shí)現(xiàn)一個(gè)掃雷小游戲

    用C語言實(shí)現(xiàn)一個(gè)掃雷小游戲

    這篇文章主要為大家詳細(xì)介紹了用C語言實(shí)現(xiàn)一個(gè)掃雷小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • C++淺拷貝與深拷貝及引用計(jì)數(shù)分析

    C++淺拷貝與深拷貝及引用計(jì)數(shù)分析

    這篇文章主要介紹了C++淺拷貝與深拷貝及引用計(jì)數(shù)分析的相關(guān)資料,需要的朋友可以參考下
    2017-06-06
  • C++讀入XML文件示例

    C++讀入XML文件示例

    本篇文章主要介紹了C++讀入XML文件,讀取和設(shè)置xml配置文件是最常用的操作,TinyXML是一個(gè)開源的解析XML的C++解析庫,感興趣的小伙伴們可以參考一下。
    2016-12-12
  • C語言結(jié)構(gòu)體占用內(nèi)存深入講解

    C語言結(jié)構(gòu)體占用內(nèi)存深入講解

    這篇文章主要給大家介紹了關(guān)于C語言結(jié)構(gòu)體占用內(nèi)存的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • C語言的預(yù)處理介紹

    C語言的預(yù)處理介紹

    大家好,本篇文章主要講的是C語言的預(yù)處理介紹,感興趣的同學(xué)趕快來看一看吧,對(duì)你有幫助的話記得收藏一下,方便下次瀏覽
    2021-12-12

最新評(píng)論

宝山区| 如皋市| 噶尔县| 林周县| 弥勒县| 喜德县| 灵璧县| 恩施市| 天祝| 大英县| 秦皇岛市| 阿克苏市| 林西县| 宁乡县| 安塞县| 阿城市| 东至县| 剑阁县| 正阳县| 襄樊市| 建阳市| 南江县| 奉节县| 金堂县| 乡城县| 衡山县| 红安县| 虹口区| 台南市| 莱州市| 新晃| 龙胜| 石泉县| 攀枝花市| 麻城市| 伊通| 江川县| 新建县| 陕西省| 永定县| 湖北省|