Шаг 65.
Библиотека 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[])
{
  auto_ptr <int> p(new int(42));
  auto_ptr <int> q;
  cout << ToRus("После инициализации:") << endl;
  cout <<" p: " << p << endl;
  cout <<" q: " << q << endl;
  q = p;
  cout << ToRus("После передачи прав владения:") << endl;
  cout <<" p: " << p << endl;
  cout <<" q: " << q << endl;
  *q += 13; // Модификация объекта, принадлежащего q
  p = q;
  cout << ToRus("После модификации и передачи прав владения:") << endl;
  cout <<" p: " << p << endl;
  cout <<" q: " << q << endl;

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

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


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

    Обратите внимание: второй параметр функции оператора вывода объявлен как константная ссылка, поэтому auto_ptr используется без передачи права владения.

    Как упоминалось на шаге 59, экземпляры auto_ptr не могут инициализироваться с присваиванием, а также им не могут присваиваться обычные указатели:

std::auto_ptr <int> p(new int(42));  //OK
std::auto_ptr<int> p = new int(42);  // ОШИБКА
p = std::auto_ptr <int> (new int(42));  // OK
p = new int(42);  // ОШИБКА

    Дело в том, что конструктор, используемый для создания auto_ptr на базе обычного указателя, объявлен с ключевым словом explicit (см. шаг 38).

    На следующем шаге мы закончим изучение этого вопроса.




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