ar ‹‹ (WORD) m_pointArray.size();

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

   ar ‹‹ *i;

 } else {

  WORD w;

  ar ›› w; // pen width

  m_nPenWidth = w;

  m_pointArray.clear();

  ar ›› w; // array size

  CPoint point;

  m_pointArray.reserve(w);

  for (int i = 0; i ‹ w; ++i) {

   ar ›› point; m_pointArray.push_back(point);

  }

 }

}

2.4.4 Archive iterators

Since CArchive is defined to work like istream and ostream, it is desirable to define a CArchive_input_iterator and a CArchive_output_iterator that will work like the istream_iterator and ostream_iterator. The loops can then be replaced by a call to the copy algorithm.

2.4.4.1 CArchive_output_iterator

Adapting the output_iterator to become the CArchive_output_iterator is very straightforward. Merely replace ostream with CArchive. The result is as follows:

template ‹class T›

class CArchive_output_iterator: public  std::iterator‹std::output_iterator_ tag, void, void› {

protected:

 CArchive* archive;

public:

 CArchive_output_iterator(CArchive& s): archive(&s) {}

 CArchive_output_iterator‹T›& operator=(const T& value) {

  *archive ‹‹ value;

  return *this;

 }

 CArchive_output_iterator‹T›& operator*() {return *this;}

 CArchive_output_iterator‹T›& operator++() {return *this;}

 CArchive_output_iterator‹T›& operator++(int) {return *this;}

};

2.4.4.2 CArchive_input_iterator

The loop to read a stroke must terminate after all of the points for that stroke have been read. This is not at the end of the input stream. We will need to pass to the copy algorithm a CArchive_input_iterator that represents the current file position as the first argument, and a CArchive_input_iterator that represents the position at which the copy operator should stop. If we were copying from a standard array, the copy call would look something like this:

copy(start, start+n, destination);

Therefore, we overload the + operator so that a CArchive_input_iterator plus an int will result in a CArchive_input_iterator object that can be used by the equality operator called by the copy algorithm to terminate the loop.

In istream_iterator the data value is extracted from the istream when the iterator object is first created and whenever the ++ operator is called. The dereferencing operator (*) then retrieves the saved value. Since we do not want to extract an object from the CArchive once the specified number of objects have been retrieved, we set a flag to indicate the need to retrieve a new object, and have the actual extraction performed by the * operator. The resulting implementation of CArchive_input_iterator is as follows:

template ‹class T›

class CArchive_input_iterator: std::iterator‹std::input_iterator_t ag, T, ptrdiff_t› {

 friend bool operator==(const CArchive_input_iterator‹T›& x, const CArchive_input_iterator‹T›& y);

 friend bool operator!=(const CArchive_input_iterator‹T›& x, const CArchive_input_iterator‹T›& y);

protected:

 CArchive* archive;

 T value;

 bool flag; // True to indicate that value is defined

 int count; // Count of the number of times ++ has been

                 // applied Or the target value for the number of advances

public:

 CArchive_input_iterator(): archive(0), flag(false), count(0) {}

 CArchive_input_iterator(CArchive& s): archive(& s), count(0), flag (false) {}

 const T& operator*() {

  if (flag) { return value; }

  else {

   *archive ›› value;

   flag = true;

   return value;

  }

 }

 CArchive_input_iterator‹T›& operator++() {

  ++count;

  flag = false;

  return *this;

 }

 CArchive_input_iterator‹T› operator++(int) {

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

0

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

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