На этом шаге мы рассмотрим пример использования класса 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).
На следующем шаге мы закончим изучение этого вопроса.