Шаг 66.
Библиотека STL.
Вспомогательные средства. Класс auto_ptr. Примеры использования (окончание)

    На этом шаге мы рассмотрим еще один пример использования класса auto_ptr.

    Следующий пример демонстрирует поведение константных объектов auto_ptr.

//---------------------------------------------------------------------------

#include <vcl.h>
#include <iostream>
#include <memory>
#include <winuser.h>
#include <conio.h> //необходимо для getch()
#pragma hdrstop

//---------------------------------------------------------------------------

#pragma argsused
using namespace std;
std::string ToRus(const std::string &in)
{
  char *buff = new char [in.length()+1];
  CharToOem(in.c_str(),buff);
  std::string out(buff);
  delete [] buff;
  return out;
}

// Определение оператора вывода для auto_ptr
// - вывод значения объекта или NULL
template <class T>
ostream& operator<< (ostream& strm, const auto_ptr<T>& p)
{
  // Указывает ли р на объект?
  if (p.get() == NULL)
  {
    strm << "NULL";  // НЕТ: вывести строку NULL
  }
  else
  {
    strm << *p;      // ДА: вывести объект
  }
  return strm;
}

int main(int argc, char* argv[])
{
  const auto_ptr <int> p(new int(42));
  const auto_ptr <int> q(new int(0));
  const auto_ptr <int> r;
  cout << ToRus("После инициализации:") << endl;
  cout <<" p: " << p << endl;
  cout <<" q: " << q << endl;
  cout <<" r: " << r << endl;
  *q = *p;
  // ОШИБКА: неопределенное поведение
  // *r = *p;
  *p = -77;
  cout << ToRus("После придания значений:") << endl;
  cout <<" p: " << p << endl;
  cout <<" q: " << q << endl;
  cout <<" r: " << r << endl;
  // ОШИБКА компиляции
  // q = p;
  // ОШИБКА компиляции
  // r = p;

  getch();
  return 0;
}
//---------------------------------------------------------------------------
Текст этого примера можно взять здесь.

    Результат выполнения программы:


Рис.1. Результат работы приложения

    В примере определен оператор вывода для auto_ptr, при этом объект auto_ptr передается по константной ссылке. Как упоминалось на шаге 62, передавать auto_ptr функциям не рекомендуется; данная функция является исключением.

    Обратите внимание: следующее присваивание является ошибкой:

  *r = *р;

    В этом присваивании производится разыменование экземпляра auto_ptr, не ссылающегося на объект. В соответствии со стандартом это приводит к непредсказуемым последствиям (например, аварийному завершению программы). Как показывает приведенный пример, вы можете работать с объектами, на которые ссылается константный указатель auto_ptr, но не можете изменять принадлежащие им объекты. Даже если бы переменная r была объявлена неконстантной, последняя команда была бы невозможной из-за модификации константы р.

    Со следующего шага мы дадим подробное описание класса auto_ptr.




Предыдущий шаг Содержание Следующий шаг