into a call to a function of one argument, where that argument is the dereferenced iterator. Stroustrup[4] shows how to do this using the binders and adapters. The function mem_fun1 is a function of one parameter, the a pointer to member function that takes an arbitrary argument. The result of this function, is a function object that takes two arguments, the first of which is a pointer to a class, and the second is the same arbitrary second argument. Thus, the expression

(*i)-›DrawStroke(pDC);

may be replaced by

mem_fun1(&CStroke::DrawStroke)(*i, pDC);

We can now apply the bind2nd binder to convert this expression into a call to a function taking one argument:

bind2nd(mem_fun1(&CStroke::DrawStroke), pDC)(*i);

The loop can now be replaced by a call to the for_each algorithm:

for_each(strokeList.begin(), strokeList.end(), bind2nd(mem_fun1(&CStroke::DrawStroke), pDC));

2.3.3 Drawing a stroke

The original code to draw a stroke was as follows:

pDC-›MoveTo(m_pointArray[0]);

for (int i=1; i ‹ m_pointArray.GetSize(); i++) {

 pDC-›LineTo(m_pointArray[i]);

}

We also make two changes. The first is to use the vector iterator as follows:

pDC-›MoveTo(m_pointArray.begin());

for (vector‹CPoint›::iterator i= m_pointArray.begin(); i!= m_pointArray.end(); + +i)

 pDC-›LineTo(*i);

Now the member function we are calling is not a member of the class pointed to by the objects in the container, but rather it is a member of the class CDC, which encapsulates the Windows® drawing context. The same mem_fun1 adapter may be used as follows:

mem_fun1(&CDC::LineTo) (pDC, *i);

Since LineTo is an overloaded function, we need to give the compiler some help resolving the ambiguity. This is done as follows:

typedef BOOL (CDC::*ptr_to_fcn_of_POINT) (POINT);

ptr_to_fcn_of_POINT p =&CDC::LineTo;

mem_fun1(p)(pDC, *i)

Since the loop variable is now the second argument, and the pDC is the first, we use bind1st to call the for_each algorithm as follows:

for_each(m_pointArray.begin(), m_pointArray.end(), bind1st(std::mem_fun1(p), pDC));

2.4 Serialization

2.4.1 Brief description of the MFC serialization

MFC provides a method for saving and retrieving a class to/from a file. The general approach is to write/read the raw bytes to the file preceded by some type identification. This is accomplished using the class CObject as an abstract base class, the virtual function serialize, and the class CArchive. CArchive encapsulates the file and provides overloaded insertion (‹‹) and extraction (››) operators. These operators are provided for the built-in types, the standard Windows® types such as WORD, DWORD, and POINT, and pointers to CObject. The insertion operator for pointers to CObject writes type identification to the file, and then calls the serialize member function. The extraction operator verifies the type identification and then calls the serialize member function.

2.4.2 The serialize function

The generalize scheme for the serialize function is as follows:

void CMyClass::Serialize(CArchive& ar) {

 CObject::Serialize(ar);

 if (ar.IsStoring()) {

  // insert the member objects into ar

 } else {

  // extract the member objects from ar

 }

}

2.4.3 Serializing the stroke list and the stroke

The straightforward implementation of serialize for CStrokeList and CStroke are as follows:

void CStrokeList::Serialize(CArchive& ar) {

 CObject::Serialize(ar);

 if (ar.IsStoring()) {

  ar ‹‹ (WORD) size ();

  for(list‹CStroke*›::iterator it = begin(); it!= end(); ++it) ar ‹‹ *it;

 } else {

  WORD s;

  ar ›› s; // get size

  clear();

  for (int i = 0; i!=s; i ++)

  {

   ar ›› temp; push_back(temp);

  }

 }

}

void CStroke::Serialize(CArchive& ar) {

 CObject::Serialize(ar);

 if (ar.IsStoring()) {

  ar ‹‹ (WORD)m_nPenWidth;

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату
×