亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C++ > 正文

通過c++11改進我們的模式之改進命令模式

2020-01-26 15:42:46
字體:
來源:轉載
供稿:網友

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

  命令模式的作用是將請求封裝為一個對象,將請求的發起者和執行者解耦,支持對請求排隊以及撤銷和重做。它的類圖如下:


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

構造器存儲接收者和對應實例變量中行為。Execute操作實施接收者的這個動作。

為創建一個調用MyClass類的一個實例上的Action行為的Command對象,僅需要如下代碼:

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

c++11改進命令模式

  要完美的解決命令模式類爆炸問題的關鍵是如何定義個通用的泛化的命令類,這個命令類可以泛化所有的命令,而不是GOF提到的簡單命令。我們再回過頭來看看GOF中那個簡單的命令類的定義,它只是泛化了沒有參數和返回值的命令類,命令類內部引用了一個接收者和接收者的函數指針,如果接收者的行為函數指針有參數就不能通用了,所以我們要解決的關鍵問題是如何讓命令類能接受所有的成員函數指針或者函數對象。
  有沒有一個能接受所有成員函數、普通函數和函數對象的類呢?有,在c++11中可以有,我上一篇博文中提到了一個萬能的函數包裝器,它可以接受所有的函數對象、fucntion和lamda表達式,它行不行呢?不行,因為它還不夠完美,它還不能接受成員函數呢,所以它還不是真正的萬能的函數包裝器。我打算在它的基礎上再擴展一下,讓它為一個真正的萬能的函數包裝器。

  接受function、函數對象、lamda和普通函數的包裝器:

復制代碼 代碼如下:

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

接受成員函數的包裝器:

復制代碼 代碼如下:

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讓它能接收成員函數。這樣一個真正意義上的萬能的函數包裝器就完成了?,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();
}
};

測試代碼:

復制代碼 代碼如下:

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

我們在通用的命令類內部定義了一個萬能的函數包裝器,使得我們可以封裝所有的命令,增加新的請求都不需要重新定義命令了,完美的解決了命令類爆炸的問題。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
8x拔播拔播x8国产精品| 久久精品视频一| 日韩高清电影好看的电视剧电影| 亚洲福利视频网| 欧美精品国产精品日韩精品| 欧美另类xxx| 一本色道久久综合狠狠躁篇的优点| 国产suv精品一区二区| 国产欧美最新羞羞视频在线观看| 久久亚洲影音av资源网| 亚洲老头老太hd| 全亚洲最色的网站在线观看| 欧美日韩在线视频观看| 亚洲第一中文字幕| 久久久精品视频在线观看| 欧美日韩亚洲高清| 亚洲欧洲在线播放| 亚洲欧洲日本专区| 97超碰蝌蚪网人人做人人爽| 国产成人精品优优av| 日韩在线观看免费高清| 国产欧美精品一区二区三区-老狼| 国产欧美韩国高清| 亚洲男女自偷自拍图片另类| 亚洲乱码国产乱码精品精天堂| 黑人狂躁日本妞一区二区三区| 亚洲精品国产拍免费91在线| 亚洲精品动漫100p| 国内揄拍国内精品少妇国语| 日韩在线视频网站| 一区二区亚洲精品国产| 久久久久成人网| 欧美精品videossex性护士| 亚洲人成自拍网站| 亚洲成人xxx| 欧美视频在线免费看| 亚洲四色影视在线观看| 在线日韩欧美视频| 精品久久久久久久中文字幕| 91精品国产91久久久久| 色爱精品视频一区| 亚洲国产免费av| 久久精品国产精品| 国产精品第七影院| 国产欧美一区二区三区视频| 成人乱人伦精品视频在线观看| 日本视频久久久| 91精品啪在线观看麻豆免费| 欧美日韩免费在线观看| 欧美性少妇18aaaa视频| 亚洲乱码一区av黑人高潮| 精品国产区一区二区三区在线观看| 欧美大片在线影院| 成人欧美在线观看| 欧美性一区二区三区| 国产91精品最新在线播放| 久久频这里精品99香蕉| …久久精品99久久香蕉国产| 日韩在线一区二区三区免费视频| 亚洲第一免费网站| 国产精品爽爽爽爽爽爽在线观看| 美女视频久久黄| 欧美激情第三页| 成人a在线视频| 久99九色视频在线观看| 日产日韩在线亚洲欧美| 国产丝袜一区二区三区| 欧美日韩国产精品| 亚洲第一精品电影| 欧美激情视频在线免费观看 欧美视频免费一| 亚洲精品自产拍| 久久天天躁狠狠躁夜夜躁| 国产精品综合网站| 亚洲色图偷窥自拍| 深夜福利一区二区| 日韩中文字幕视频在线| 国产亚洲福利一区| 亚洲香蕉成视频在线观看| 欧美国产一区二区三区| 亚洲男女性事视频| 亚洲国产婷婷香蕉久久久久久| 日韩最新av在线| 日韩视频在线观看免费| 2020欧美日韩在线视频| 亚洲韩国欧洲国产日产av| 欧美一区二区三区艳史| 久久久91精品国产一区不卡| 欧美一区二区色| 精品香蕉一区二区三区| 国产精品久久一区主播| 久久久久在线观看| 91久久久久久久一区二区| 国产精品视频白浆免费视频| 久久久免费精品| 亚洲色图17p| 国产91在线高潮白浆在线观看| 国产欧美 在线欧美| 欧美激情一区二区三区久久久| 久久亚洲国产成人| 狠狠久久五月精品中文字幕| 欧美在线免费视频| 日韩视频免费看| 国产久一一精品| 久久综合久中文字幕青草| 久久久久久久久国产| 中文字幕国产日韩| 亚洲精品成人网| 一区二区欧美在线| 欧美www视频在线观看| 亚洲激情视频在线播放| 欧美激情视频网| 8x海外华人永久免费日韩内陆视频| 国色天香2019中文字幕在线观看| 欧美精品在线视频观看| 欧美中文在线观看| 亚洲国产精品系列| 久久久亚洲影院你懂的| 中文字幕日韩电影| 久久97精品久久久久久久不卡| 国产精品精品一区二区三区午夜版| 久久精品99久久久香蕉| 精品动漫一区二区三区| 亚洲精品久久久久| 国产精品毛片a∨一区二区三区|国| 亚洲国产精品高清久久久| 久久69精品久久久久久国产越南| 国语自产精品视频在线看抢先版图片| 国产成人精彩在线视频九色| 日av在线播放中文不卡| 精品久久久久久亚洲精品| 一区二区三区四区视频| 亚洲一级免费视频| 日韩在线欧美在线国产在线| 一本一本久久a久久精品综合小说| 欧美极品少妇xxxxⅹ喷水| 欧美日韩第一视频| 国产精品久久久久久久久影视| 欧美激情国产高清| 91亚洲一区精品| 国产精品综合久久久| 国产日韩欧美自拍| 91精品成人久久| 成人一区二区电影| 久久久av免费| 国产精选久久久久久| 国产欧美日韩精品专区| 国产成人精品999| 久久99国产综合精品女同| 4p变态网欧美系列| 日韩激情在线视频| 一区二区三区国产视频| y97精品国产97久久久久久| 国产91成人在在线播放| 成人久久久久久| 岛国av一区二区| 久久91亚洲精品中文字幕奶水| 一区二区三区视频观看| 91免费人成网站在线观看18| 成人a在线观看| 欧美激情一区二区三区成人| 91精品久久久久久久久青青| 国内精品久久久久影院优| 136fldh精品导航福利| 欧美xxxx18国产|