Шаг 72.
Библиотека STL. Вспомогательные средства. Описание класса auto_ptr. Пример реализации класса auto_ptr

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

    Ниже приведен пример реализации класса auto_ptr, отвечающей требованиям стандарта.

// Класс auto_ptr - усовершенствованная реализация, 
// соответствующая стандарту. 
namespace std 
{
  // Вспомогательный тип, 
  // используемый при копировании и присваивании 
  // (теперь является глобальным) 
  tempiate<class Y> 
  struct auto_ptr_ref { 
    Y* yp;
    auto_ptr_ref (Y* rhs) : 
      yp(rhs) {
    }
  };

  template<class T> 
  class auto_ptr {
    private:
      T* ар; // Указывает на принадлежащий объект 
    public:
      typedef T element_type;
      // Конструктор
      explicit auto_ptr (T* ptr = 0) throw() 
        : ap(ptr) {}

      // Копирующие конструкторы (с неявным преобразованием типа) 
      // Обратите внимание - параметр объявлен неконстантным! 
      auto_ptr (auto_ptr& rhs) throw() 
        : ap(rhs.release()) {
      }
      tempiate<class Y>
      auto_ptr (auto_ptr<Y>& rhs) throw() 
        : ap(rhs.release()) { }
      // Операторы присваивания (с неявным преобразованием типа) 
      // Обратите внимание - параметр объявлен неконстантным! 
      auto_ptr& operator= (auto_ptr& rhs) throw() {
        reset(rhs.release());
        return *this;
      }

      template<class Y>
      auto_ptr& operator= (auto_ptr<Y>& rhs) throw() {
        reset(rhs.release());
        return *this;
      }

      // Деструктор 
      ~auto_ptr() throw() { 
        delete ap;
      }

      // Обращение по указателю 
      T* get() const throw() { 
        return ap;
      }
      T& operator*() const throw() { 
        return *ap;
      }
      T* operator->() const throw() { 
        return ap;
      }

      // Освобождение принадлежащего объекта
      Т* release() throw() { 
        Т* tmp(ap); 
        ар = 0; 
        return tmp;
      }

      // Повторная инициализация 
      void reset (T* ptr=0) throw() { 
        if (ap != ptr) {
          delete ap;
          ap = ptr;
        }
      }

      // Специальные преобразования с применением вспомогательного типа, 
      // используемые при копировании и присваивании 
      auto_ptr(auto_ptr_ref<T> rhs) throw() 
        : ap(rhs.yp) { }
 
      auto_ptr& operator= (auto_ptr_ref<T> rhs) throw() { //Новый
        reset(rhs.yp); 
        return *this;
      }

      template<class Y>
      operator auto_ptr_ref<Y>() throw() { 
        return auto_ptr_ref<Y>(release());
      }

      template<class Y> 
      operator auto_ptr<Y>() throw() { 
        return auto_ptr<Y>(release());
      }
    };
}


   Замечение. Учтите, что код не полностью соответствует стандарту. Оказалось, что спецификация стандарта содержит ошибки в описании специальных преобразований, выполняемых при использовании auto_ptr_ref. В представленной версии эти ошибки исправлены.

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




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