The reason is that I have read the article, and the subject is taken from "C ++ meditation". I have made full use of several design patterns and combined the so-called object-oriented techniques, and then gained my own strength, in the end, I also asked: "Is there a better solution? ". The base sighed, and another victim of design patterns. Next, we propose another solution.
First, declare a point. In reality, an image can be added with a layer after layer, or combined with other images, either horizontal or vertical ,......, However, there is always only one image. After processing it, it will always look like that. It is impossible to see both of it at the same time, or add a border, or combine it with other photos. If you copy this image, it is another matter, but it is already the first image. Of course, you can copy the modified image with a slight modification to the following example.
This topic is writing a message framework recently. If this example can use that framework, it will be easy to write. However, even if the message framework is not supported, it is quite pediatric to solve this problem by sending messages. In order to highlight the key points, various exception handling is ignored, and no optimization is made. No matter what the programming style is, it simply goes straight to the topic. The most important thing to solve this problem is to print the image one by one from the top to the bottom. 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 <m_nCount; 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 (; I <pSelf-> m_nWidth; I ++)
Out <'';
}
Return 0;
}
Void CPicture: Print (ostream & out)
{
Int nHeight = m_Imp.GetHeight ();
For (int nRow = 0; nRow <nHeight; 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 (int I = 0; I <prevImp. GetWidth (); I ++)
Out <'-';
Out <'+ ';
}
Else
{
Out <'| ';
PrevImp. PrintRow (nRow-1, out );
Out <'| ';
}
}
Return 0;
}
Class CHorseDecorater
{
Public:
CHorseDecorater (PictureImp & impLeft, PictureImp & impRight)
{
M_Left = impLeft;
M_Right = impRight;
ImpLeft. pThis = this;
ImpLeft. proc = HandleMsg;
ImpRight. pThis = this;
ImpRight. proc = HandleMsg;
}
Private:
PictureImp m_Left;
PictureImp m_Right;
Static int HandleMsg (void * pThis, int nMessage, void * param1, void * param2 );
Static void PrintRow (PictureImp & pict, int nRow, ostream & out)
{
If (nRow <pict. GetHeight ())
Pict. PrintRow (nRow, out );
Else
{
For (int I = 0; I <pict. GetWidth (); I ++)
Out <'';
}
}
};
Int CHorseDecorater: HandleMsg (void * pThis, int nMessage, void * param1, void * param2)
{
CHorseDecorater * pSelf = (CHorseDecorater *) pThis;
PictureImp & pictLeft = pSelf-> m_Left;
PictureImp & 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_PRINT_ROW:
Int nRow = (int) param1;
Ostream & out = * (ostream *) param2;
PrintRow (pictLeft, nRow, out );
PrintRow (pictRight, nRow, out );
}
Return 0;
}
Int main ()
{
Const char * init1 [] = {"Paris", "in the", "Spring", "HaHa "};
CPicture pict1 (init1, 3 );
Pict1.Print (cout );
CFrameDecorater framer1 (pict1.m _ Imp );
// Pict1.Print (cout );
CFrameDecorater framer2 (pict1.m _ Imp );
Pict1.Print (cout );
CPicture pict2 (init1, 4 );
CHorseDecorater hors (pict1.m _ Imp, pict2.m _ Imp );
Pict1.Print (cout );
CFrameDecorater framerHorse (pict1.m _ Imp );
Pict1.Print (cout );
Return 0;
}
Well, you can see it at a Glance. Cut, this is just a trick to imitate WINDOWS window message processing functions. No inheritance or virtual functions!
Note that, although pict1 is decorated several times, its image printing is always pict1.Print (cout ). The so-called no matter the eight winds, I can't move