设为首页 加入收藏

TOP

消息发送VS设计模式 C++沉思录的一练习题的另解(一)
2014-11-24 00:04:11 来源: 作者: 【 】 浏览:61
Tags:消息 发送 设计模式 沉思 习题
缘起,看到一遍文章,题材取自于《C++沉思录》,综合利用好几种设计模式,并且结合所谓的面向对象的技巧,然后洋洋自得,并且在最后,还反问:“有更好的解决方案吗?”。本座暗叹,又一个设计模式的毒害者。以下,就提出另一种解决方案。

首先,先声明一点,现实中,一张图片,可以给予添加一层又一层片框,也可以和其他的图片组合在一块,或横,或竖,……,但是,图片,始终只有一张,对它处理之后,它就一直是那个样子了,不可能同时看到它的两个样子,或加边框,或和其他照片组合在一块。如果,拿这张图片去进行复制,那又自是另当别论,但那已经是另外一第图片了。当然,对以下例子稍加修改,就能支持修饰的图片的复制操作。

本座最近在写一套消息框架,如果这个例子能用上那套框架,写起来就会很简单。但是,即使没有消息框架的支持,利用消息发送来解决这个问题,也是相当小儿科的事情。为了突出重点,忽略了各种异常处理,没有优化,也不管什么 编程风格,纯粹直奔主题。解决这个例子的最重要一点,就在于打印图片时,要一行一行地从顶到底顺次打印下来。 www.2cto.com


typedef int (*ProcPictureImp)(void* pThis, int nMessage, void* param1, void* param2);

enum { PM_WIDTH, PM_HEIGHT, PM_PRINT_ROW};

struct PictureImp
{
void* pThis;
ProcPictureImp proc;

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

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

int PrintRow(int nRow, ostream& out)
{
return (*proc)(pThis, PM_PRINT_ROW, (void*)nRow, (void*)&out);
}
};


class CPicture
{
public:
CPicture(const char* pDatas[], int nCount)
{
m_pDatas = pDatas;
m_nCount = nCount;
m_nWidth = 0;
for (int i=0; i {
int nLen = strlen(m_pDatas[i]);
if (m_nWidth < nLen)
m_nWidth = nLen;
}
m_Imp.pThis = this;
m_Imp.proc = HandleMsg;
}
void Print(ostream& out);

public:
PictureImp m_Imp;

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_PRINT_ROW:
int nRow = (int)param1;
ostream& out = *(ostream*)param2;
if (nRow >= pSelf->m_nCount)
break;
int i=0;
for (; pSelf->m_pDatas[nRow][i] != 0; i++)
out << pSelf->m_pDatas[nRow][i];
for (; im_nWidth; i++)
out << ' ';
}
return 0;
}

void CPicture::Print(ostream& out)
{
int nHeight = m_Imp.GetHeight();
for (int nRow = 0; nRow {
m_Imp.PrintRow(nRow, out);
out << endl;
}
}

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

private:
PictureImp 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;
PictureImp& prevImp = pSelf->m_PrevImp;
switch (nMessage)
{
case PM_WIDTH:
return prevImp.GetWidth()+2;

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

case PM_PRINT_ROW:
int nRow = (int)param1;
ostream& out = *(ostream*)param2;
bool bMyRow = nRow == 0 || nRow>prevImp.GetHeight();
if (nRow >= prevImp.GetWidth()+2)
break;
if (nRow == 0 || nRow>prevImp.GetHeight())
{
out << '+';
for (in
首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇一种简单的跨平台用户态自旋锁 下一篇C语言实现《大话设计模式》中的观..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: