青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

huaxiazhihuo

 

C++沉思錄課堂練習另解--消息發送(優化版)

          緣起,看到一篇文章(懶得超鏈接),重新研究《C++沉思錄》的那一個課堂練習,綜合利用好幾種設計模式,并且很好地遵守結合的面向對象的原則,嗯,不管怎么樣,還是表揚這位同學的面向對象與設計模式的功力,確實不容易。只是,在下從模式堆里爬出來之后,已經對模式大倒胃口,看到這么小的練習,居然要用上這么多模式,一時技癢,有必要這樣嗎?對我來說,代碼中每引入一種模式,就表示要添加各種接口、虛函數,然后,免不了就要用到繼承,這些,我非常深痛惡疾,因為,這都意味著間接層越來越厚了,偏離了問題的本質。
          先看看沉思錄對于這道題的描述,嗯,這個,還是請各位自己去看看書是怎么寫的,作者提供了兩種方案,佩服作者和譯者的文筆,兩種方案解釋得相當細膩。下面,嘗試另一種解決方式。先秀一下代碼的運行效果。
          對于這個課堂練習,其中,給圖片加邊框,最適合于用裝飾模式來解決。但是,兩幅圖片的橫接、豎接,怕是就不那么容易了。但是,首先,要對問題重新描述一下,現實中,一張圖片,可以給予添加一層又一層的片框,也可以和其他的圖片組合在一塊,或橫,或豎,……,但是,圖片,始終只有一張,對它處理之后,它就一直是那個樣子了,不可能同時看到它的兩個樣子。如果,拿這張圖片去進行復制,那又自是另當別論,但那已經是另外一張新圖片了。
          以下的設計用上了消息,如果有現成消息框架給予支持,實現起來就會很簡單。但是,即使沒有消息框架的支持,利用消息發送來解決這個問題,也是相當小兒科的事情。為了突出重點,忽略了各種異常處理,沒有優化,也不管什么編程風格,純粹直奔主題。解決這個例子的最重要一點,就在于打印圖片時,要一行一行地從頂到底順次打印下來。因此,先定義這個圖片可以發送的消息,它必須處理兩條消息,圖片的高度(即行數),和圖片每一行的數據。即如下所示
enum {PM_HEIGHT, PM_ROW};

struct PictureMsg
{
    typedef 
int (*ProcPictureMsg)(void* pThis, int nMessage, void* param1, void* param2);
public:
    
void* pThis;
    ProcPictureMsg proc;

    
int GetHeight()
    
{
        
return (*proc)(pThis, PM_HEIGHT, NULL, NULL);
    }


    
int GetRow(int nRow, string& sRow)
    
{
        
return (*proc)(pThis, PM_ROW, (void*)nRow, (void*)&sRow);
    }

}
;
ostream
& operator << (ostream& out, PictureMsg& msg)
{
    
int nHeight = msg.GetHeight();
    
string sRow;
    
for (int nRow = 0; nRow<nHeight; nRow++)
    
{
        sRow.clear();
        msg.GetRow(nRow, sRow);
        
out << sRow;
        
out << endl;
    }

    
return out;
}

          其中的回調函數用以發送消息,本來回調函數搞成成員函數會更加好,但由于c++的成員函數是一個大坑,而我又不想引入function或者其他delegate等龐然大物。為了讓客戶更加方便地發送消息,特意編寫了兩個輔助函數。
          但是,要發送消息給對象時,首先要求這個對象必須已經活著了,也即是要創建一個能接收消息的對象。由于沒有消息框架的支持,同時,也為了使用上的方便,我只好編寫一個具體的類繼承于圖片消息結構,并提供了初步的消息處理,嗯,用到了繼承,很難受。
          好了,接下來就可以全心全意地對消息進行特別地處理了。要求,對圖片的各種裝飾操作,不能影響到圖片原有的功能,也不要求改變用戶的代碼?;蛘哒f,圖片本身并不知道自己已經被外界做了各種各樣的處理,它還是按照原來的樣子處理各種消息。下面,只是實現了兩種裝飾操作,加邊框與橫接,至于豎接,實在很容易實現的。此外,由于在實現裝飾操作時,需要用到圖片的寬度,因此,圖片消息又添加了一條新的消息,用以處理圖片的寬度。
由于是玩具代碼,在下也沒有做太大的優化,有幾行代碼顯得特別難看,特別是橫接的裝飾方法,強制指定了左邊的圖片為操作后的結果,還有各個裝飾類的析構函數,可以撤消對圖片的裝飾,以及添加新的消息,以返回圖片的拷貝,或返回當前正在進行的裝飾操作,或者裝飾類的動態創建等等??傊?,可優化升級的方法多種多樣,而且都不會影響代碼的結構。以下,是一陀代碼,從第一版上稍加優化的,不讀也罷。

enum { PM_WIDTH, PM_HEIGHT, PM_ROW};

struct PictureMsg
{
    typedef 
int (*ProcPictureMsg)(void* pThis, int nMessage, void* param1, void* param2);
public:
    
void* pThis;
    ProcPictureMsg proc;

    
int GetWidth()
    
{
        
return (*proc)(pThis, PM_WIDTH, NULL, NULL);
    }


    
int GetHeight()
    
{
        
return (*proc)(pThis, PM_HEIGHT, NULL, NULL);
    }


    
int GetRow(int nRow, string& sRow)
    
{
        
return (*proc)(pThis, PM_ROW, (void*)nRow, (void*)&sRow);
    }

}
;

ostream
& operator << (ostream& out, PictureMsg& msg)
{
    
int nHeight = msg.GetHeight();
    
string sRow;
    
for (int nRow = 0; nRow<nHeight; nRow++)
    
{
        sRow.clear();
        msg.GetRow(nRow, sRow);
        
out << sRow;
        
out << endl;
    }

    
return out;
}


class CPicture : public PictureMsg
{
public:
    CPicture(
const char* pDatas[], int nCount)
    
{
        m_pDatas 
= pDatas;
        m_nCount 
= nCount;
        m_nWidth 
= 0;
        
for (int i=0; i<m_nCount; i++)
        
{
            
int nLen = strlen(m_pDatas[i]);
            
if (m_nWidth < nLen)
                m_nWidth 
= nLen;
        }

        pThis 
= this;
        proc 
= HandleMsg;
    }


private:
    
const char** m_pDatas;
    
int m_nCount;
    
int m_nWidth;

    
static int HandleMsg(void* pThis, int nMessage, void* param1, void* param2);
}
;

int CPicture::HandleMsg(void* pThis, int nMessage, void* param1, void* param2)
{
    CPicture
* pSelf = (CPicture*)pThis;
    
switch (nMessage)
    
{
    
case PM_WIDTH:
        
return pSelf->m_nWidth;

    
case  PM_HEIGHT:
        
return pSelf->m_nCount;
        
break;

    
case PM_ROW:
        
int nRow = (int)param1;
        
string& sRow = *(string*)param2;
        
if (nRow >= pSelf->m_nCount)
            
break;
        
int i=0
        
for (; pSelf->m_pDatas[nRow][i] != 0; i++)
            sRow.push_back(pSelf
->m_pDatas[nRow][i]);
        
for (; i<pSelf->m_nWidth; i++)
            sRow.push_back(
' ');                
    }

    
return 0;
}



class CFrameDecorater
{
public:
    CFrameDecorater(PictureMsg
& imp)
    
{
        m_PrevImp 
= imp;
        imp.pThis 
= this;
        imp.proc 
= HandleMsg;
    }


private:
    PictureMsg m_PrevImp;
    
static int HandleMsg(void* pThis, int nMessage, void* param1, void* param2);
}
;

int CFrameDecorater::HandleMsg(void* pThis, int nMessage, void* param1, void* param2)
{
    CFrameDecorater
* pSelf = (CFrameDecorater*)pThis;
    PictureMsg
& prevImp = pSelf->m_PrevImp;
    
switch (nMessage)
    
{
    
case PM_WIDTH:
        
return prevImp.GetWidth()+2;

    
case  PM_HEIGHT:
        
return prevImp.GetHeight()+2;

    
case PM_ROW:
        
int nRow = (int)param1;
        
string& sRow = *(string*)param2;
        
bool bMyRow = nRow == 0 || nRow>prevImp.GetHeight();
        
if (nRow >= prevImp.GetWidth()+2)
            
break;
        
if (nRow == 0 || nRow>prevImp.GetHeight())
        
{
            sRow.push_back(
'+');
            
for (int i=0; i<prevImp.GetWidth(); i++)
                sRow.push_back(
'-');
            sRow.push_back(
'+');
        }

        
else
        
{
            sRow.push_back(
'|');
            prevImp.GetRow(nRow
-1, sRow);
            sRow.push_back(
'|');
        }

    }

    
return 0;
}



class CHorseDecorater
{
public:
    CHorseDecorater(PictureMsg
& impLeft, PictureMsg& impRight)
    
{
        m_Left 
= impLeft;
        m_Right 
= impRight;
        impLeft.pThis 
= this;
        impLeft.proc 
= HandleMsg;
    }


private:
    PictureMsg m_Left;
    PictureMsg m_Right;

    
static int HandleMsg(void* pThis, int nMessage, void* param1, void* param2);
    
static void PrintRow(PictureMsg& pict, int nRow, string& sRow)
    
{
        
if (nRow < pict.GetHeight())
            pict.GetRow(nRow, sRow);
        
else
        
{
            
for (int i=0; i<pict.GetWidth(); i++)
                sRow.push_back(
' ');
        }

    }

}
;

int CHorseDecorater::HandleMsg(void* pThis, int nMessage, void* param1, void* param2)
{
    CHorseDecorater
* pSelf = (CHorseDecorater*)pThis;
    PictureMsg
& pictLeft = pSelf->m_Left;
    PictureMsg
& pictRight = pSelf->m_Right;
    
switch (nMessage)
    
{
    
case PM_WIDTH:
        
return pictLeft.GetWidth()+pictRight.GetWidth();;

    
case  PM_HEIGHT:
        
return max(pictLeft.GetHeight(), pictRight.GetHeight());

    
case PM_ROW:
        
int nRow = (int)param1;
        
string& sRow = *(string*)param2;
        PrintRow(pictLeft, nRow, sRow);
        PrintRow(pictRight, nRow, sRow);
    }

    
return 0;
}


int main()
{
    
const char* init1[] = {"Paris""in the""Spring""HaHa"};
    CPicture pict1(init1, 
3);
    
//cout << pict1;
    CFrameDecorater framer1(pict1);
    
//cout << pict1;
    CFrameDecorater framer2(pict1);
    
//cout << pict1;
    CPicture pict2(init1, 4);
    CHorseDecorater hors(pict1, pict2);
    
//cout << pict1;
    CFrameDecorater framerHorse(pict1);
    
//cout << pict1;
    CHorseDecorater hors2( pict2,  pict1);
    
//cout << pict2;
    CFrameDecorater framer3(pict2);
    CHorseDecorater hors3( pict1,  pict2);
    cout 
<< pict1;
    
return 0;
}



posted on 2012-06-12 23:57 華夏之火 閱讀(2109) 評論(0)  編輯 收藏 引用 所屬分類: 玩具代碼

導航

統計

常用鏈接

留言簿(6)

隨筆分類

隨筆檔案

搜索

積分與排名

最新評論

閱讀排行榜

評論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲第一区色| 国产精品黄色| 亚洲精品国久久99热| 欧美在线观看一区二区| 亚洲色图在线视频| 亚洲天堂免费观看| 亚洲无人区一区| 亚洲一级影院| 亚洲一区制服诱惑| 亚洲欧美日韩一区| 午夜伦理片一区| 久久精品国产久精国产思思| 久久久久一区二区三区| 老司机免费视频一区二区三区| 久久中文欧美| 亚洲精品国产精品国产自| 9l国产精品久久久久麻豆| 在线中文字幕日韩| 欧美一区二区三区免费大片| 久久久久久香蕉网| 欧美大尺度在线| 国产精品wwwwww| 国产亚洲欧美一区在线观看| 最新中文字幕亚洲| 亚洲综合国产| 久久综合九色| 日韩午夜激情av| 久久久另类综合| 欧美三级乱人伦电影| 国产婷婷色一区二区三区四区| 在线成人激情黄色| 亚洲一区视频在线| 噜噜噜在线观看免费视频日韩| 亚洲国产精品一区二区第一页 | 亚洲影院色在线观看免费| 亚洲欧美国产日韩天堂区| 亚洲国产一区二区三区a毛片| 野花国产精品入口| 久久精品30| 国产精品美女久久| 亚洲黄色一区二区三区| 亚洲一区二区三区视频| 欧美国产欧美亚洲国产日韩mv天天看完整 | 欧美成人亚洲| 亚洲欧美日韩国产一区| 欧美日本免费一区二区三区| 国色天香一区二区| 欧美诱惑福利视频| 一本色道久久综合亚洲精品按摩| 久久乐国产精品| 国产一区视频观看| 欧美亚洲一区三区| 一本色道久久综合精品竹菊| 欧美成人三级在线| 亚洲激情啪啪| 免费日韩成人| 欧美一区激情| 国产一区日韩欧美| 久久免费视频网| 亚洲欧美日韩国产另类专区| 国产伦精品一区二区三区照片91| 亚洲永久精品国产| 日韩亚洲视频在线| 欧美另类久久久品| 99热这里只有精品8| 欧美成人精品h版在线观看| 久久av二区| 亚洲第一视频网站| 亚洲大胆女人| 久久香蕉国产线看观看av| 国产一区二区剧情av在线| 欧美在线观看视频一区二区| 亚洲男女毛片无遮挡| 国产精品欧美日韩一区| 亚洲欧美一区二区激情| 亚洲一区二区三区免费在线观看| 国产精品久久久久久久浪潮网站 | 在线亚洲免费| 国产精品视频免费观看| 欧美在线三级| 欧美一区二区视频网站| 在线成人激情视频| 欧美激情精品久久久久久免费印度 | 狠狠色综合日日| 久久亚洲一区二区三区四区| 久久九九久久九九| 亚洲精品欧美专区| 国产伦精品一区二区三区四区免费| 欧美视频网址| 亚洲免费一级电影| 久久综合久色欧美综合狠狠 | 午夜精品婷婷| 久久久国产精品亚洲一区| 一本一本久久a久久精品综合麻豆| 欧美黄色小视频| 亚洲视频第一页| 亚洲女同性videos| 国产日韩欧美一区二区| 久久综合久久综合久久| 欧美精品三级日韩久久| 亚洲一区国产一区| 久久精品视频在线观看| 亚洲精品在线观看视频| 亚洲精品你懂的| 欧美成人高清视频| 国外精品视频| 麻豆91精品91久久久的内涵| 久久久久久成人| 狠狠做深爱婷婷久久综合一区 | 黄色成人免费网站| 久久尤物视频| 久久av免费一区| 韩国女主播一区二区三区| 久久久久欧美| 欧美视频二区36p| 久热精品在线视频| 欧美成人国产一区二区| 一二三四社区欧美黄| 欧美伊人久久久久久久久影院| 国内揄拍国内精品久久| 91久久国产综合久久| 国产欧美欧美| 亚洲黄色成人久久久| 欧美激情网站在线观看| 欧美日韩亚洲高清一区二区| 久久精品一级爱片| 欧美午夜视频网站| 久久久999成人| 国产精品亚洲综合一区在线观看| 亚洲黄色一区| 国产精品青草久久久久福利99| 欧美国产日韩视频| 国产一区二区三区四区在线观看| 中文日韩在线| 亚洲一区二区三区四区在线观看 | 日韩视频一区二区三区在线播放免费观看| 亚洲色在线视频| 亚洲视频中文字幕| 免费日韩精品中文字幕视频在线| 亚洲欧美国产高清va在线播| 国产精品日韩欧美一区二区| 在线综合亚洲| 亚洲小少妇裸体bbw| 欧美精品亚洲| 亚洲国产综合91精品麻豆| 韩国免费一区| 久久精品综合| 亚洲盗摄视频| 亚洲国产经典视频| 欧美体内谢she精2性欧美| 午夜日韩视频| 免费国产一区二区| 亚洲日本aⅴ片在线观看香蕉| 欧美激情第4页| 亚洲第一综合天堂另类专| 亚洲精品久久久一区二区三区| 另类春色校园亚洲| 亚洲午夜在线观看| 最新国产乱人伦偷精品免费网站| 夜夜夜久久久| 激情久久中文字幕| 欧美日韩国产一中文字不卡| 亚洲欧美日韩综合一区| 免费欧美电影| 久久成人这里只有精品| 亚洲午夜精品17c| 亚洲欧洲美洲综合色网| 国产美女高潮久久白浆| 欧美在线精品免播放器视频| 国产精品嫩草影院一区二区| 麻豆av一区二区三区久久| 一区二区三区四区五区在线| 91久久久久久| 欧美中文字幕| 夜夜嗨av一区二区三区中文字幕 | 在线播放中文字幕一区| 亚洲精品一区在线| 国产日韩欧美综合精品| 妖精视频成人观看www| 国产精品一区二区久久国产| 久久久噜噜噜| 美女爽到呻吟久久久久| 欧美91大片| 国产精品免费视频观看| 老司机免费视频一区二区三区 | 一本色道久久| 欧美精品乱码久久久久久按摩| 久久av一区| 国产视频精品va久久久久久| 亚洲日本中文| 一区二区三区欧美亚洲| 欧美日韩另类视频| 免费不卡中文字幕视频| 欧美激情视频免费观看| 亚洲视频福利| 久久久国产精品一区二区三区| 欧美成人精品在线播放| 一区二区欧美激情| 亚洲高清视频在线观看| 黄色精品在线看|