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

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

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>
            欧美极品在线视频| 亚洲欧美www| 欧美激情综合五月色丁香小说| 亚洲一区二区三区四区五区午夜| 91久久精品一区| 亚洲第一网站免费视频| 亚洲第一精品夜夜躁人人爽| 嫩草国产精品入口| 亚洲国产视频a| 国产精品99久久久久久久久久久久| 日韩午夜三级在线| 午夜精品久久久久| 免费一区二区三区| 欧美视频官网| 国产一区二区电影在线观看| 在线观看三级视频欧美| 99视频一区二区| 久久www成人_看片免费不卡| 理论片一区二区在线| 亚洲成人中文| 亚洲欧美视频一区| 久久五月激情| 国产精品久久久久久久久免费桃花| 国产一区二区在线观看免费| 亚洲精品国产精品国自产在线| 亚洲欧美国产77777| 麻豆精品网站| av成人免费在线| 久久久久久成人| 欧美日韩人人澡狠狠躁视频| 国产一区二区三区四区五区美女| 亚洲精品中文字| 久久久精品2019中文字幕神马| 欧美大色视频| 久久er精品视频| 国产精品成人一区二区| 狠狠色狠狠色综合日日小说| 亚洲一区二区三区中文字幕在线| 欧美xxxx在线观看| 午夜精彩视频在线观看不卡 | 久久久久久久性| 亚洲黄色免费电影| 欧美在线二区| 国产精品成人aaaaa网站 | 欧美日韩国产小视频| 精久久久久久久久久久| 欧美一站二站| 一本色道久久精品| 欧美另类视频在线| 亚洲精品国产精品久久清纯直播| 久久综合中文色婷婷| 亚洲欧美激情精品一区二区| 欧美激情第10页| 亚洲精品网站在线播放gif| 欧美高清在线视频观看不卡| 午夜欧美精品久久久久久久| 国产精品色午夜在线观看| 中国成人亚色综合网站| 亚洲激情网址| 欧美二区在线观看| 亚洲乱码精品一二三四区日韩在线 | 欧美成年人视频网站欧美| 在线日韩日本国产亚洲| 欧美成人黑人xx视频免费观看| 久久蜜桃香蕉精品一区二区三区| 国产在线播放一区二区三区| 美女精品在线观看| 欧美成人a∨高清免费观看| 亚洲乱码国产乱码精品精 | 久久精品国产96久久久香蕉| 国产一区免费视频| 欧美成人精品1314www| 免费欧美日韩| 亚洲天堂av图片| 亚洲综合丁香| 一区二区三区在线免费视频| 亚洲高清二区| 欧美午夜精品久久久久久浪潮 | 在线日韩欧美视频| 亚洲另类在线视频| 国产精一区二区三区| 久久亚洲综合色一区二区三区| 久久久成人网| 99国产精品私拍| 午夜精品成人在线| 亚洲国产日韩欧美一区二区三区| 亚洲国产精品电影在线观看| 国产精品xxxav免费视频| 久久久精品视频成人| 欧美成va人片在线观看| 香蕉久久久久久久av网站| 久久国产精品72免费观看| 国产精品美女一区二区| 国产欧美在线观看| 老司机成人网| 欧美视频在线观看| 久久男人av资源网站| 免费亚洲电影在线| 久久高清免费观看| 欧美另类变人与禽xxxxx| 久久免费高清| 国产精品扒开腿做爽爽爽视频 | 亚洲激情在线| 亚洲欧美国内爽妇网| 亚洲精品视频在线播放| 亚洲综合成人在线| 亚洲精品日韩久久| 久久久精品tv| 欧美一区二区三区四区视频| 欧美国产日韩a欧美在线观看| 久久国产直播| 欧美天天在线| 亚洲国产精品一区二区www| 国产美女精品一区二区三区| 亚洲日本乱码在线观看| 激情文学一区| 午夜在线观看免费一区| 亚洲少妇在线| 欧美大片第1页| 蜜桃久久av一区| 国产在线麻豆精品观看| 亚洲欧美成人一区二区在线电影| 99成人在线| 欧美不卡高清| 亚洲国产电影| 亚洲免费高清| 欧美人与禽性xxxxx杂性| 欧美18av| 亚洲丰满少妇videoshd| 久久精品视频免费| 久久综合999| 国产在线拍偷自揄拍精品| 午夜精品久久一牛影视| 欧美在线视频全部完| 国产精品入口66mio| 一区二区三区视频在线观看| 国产精品99久久久久久www| 欧美精品久久久久久久| 亚洲精品在线观看视频| 亚洲一区亚洲| 国产日韩精品一区| 久久黄色级2电影| 久久综合中文| 亚洲国产一区在线| 久热爱精品视频线路一| 亚洲国产日日夜夜| 亚洲视频一区| 国产精品视频一二三| 欧美一区二区三区男人的天堂| 久久综合激情| 日韩视频免费大全中文字幕| 欧美日韩一区在线视频| 一本久久a久久精品亚洲| 午夜精品999| 一区二区视频欧美| 欧美日韩国产精品专区| 亚洲无线视频| 久久蜜桃资源一区二区老牛| 亚洲福利电影| 欧美天天视频| 欧美黑人在线观看| 9l国产精品久久久久麻豆| 欧美视频你懂的| 欧美亚洲一级| 亚洲成人资源网| 亚洲尤物在线| 在线观看日韩av先锋影音电影院| 另类专区欧美制服同性| 亚洲精品一区二区三区在线观看| 午夜日本精品| 亚洲欧洲精品天堂一级| 国产精品三区www17con| 美女尤物久久精品| 亚洲午夜精品国产| 欧美激情第3页| 欧美在线视频在线播放完整版免费观看 | 日韩午夜激情| 久久一区二区三区四区| av成人免费| 激情国产一区| 欧美日韩国产在线播放| 欧美亚洲自偷自偷| 亚洲美女在线观看| 老司机久久99久久精品播放免费| 亚洲理论在线| 亚洲国产mv| 国产午夜精品全部视频在线播放| 欧美 日韩 国产 一区| 欧美一区二区免费| 亚洲最新视频在线播放| 亚洲国产成人不卡| 久久综合网络一区二区| 亚洲亚洲精品三区日韩精品在线视频| 韩国v欧美v日本v亚洲v| 国产精品露脸自拍| 欧美午夜激情在线| 欧美日韩精品一区二区| 久久免费少妇高潮久久精品99| 亚洲欧美在线视频观看| 99精品视频一区二区三区|