LINUX.ORG.RU

auto_ptr в С++


0

0

Вот такая странная проблема. Ниже я привел код класса auto_ptr
из STL. Вопрос: почему, если убрать оператор

auto_ptr& operator=(auto_ptr_ref<_Tp> __ref)

(я пометил его комментариями "// !!!!!!!!!!" ),
перестает компилироваться код вроде следующего:

auto_ptr<myclass> m;
m = new myclass; // здесь!

с руганью о ненахождении подходящего оператора присваивания??
Кто знает, объясните мне, глупому, в чем дело...


Cut here:
------------------------------------

namespace std
{

 template<class _Tp1> struct auto_ptr_ref {
   _Tp1* _M_ptr;
   auto_ptr_ref(_Tp1* __p) : _M_ptr(__p) {}
};

template <class _Tp> class auto_ptr {
private:
  _Tp* _M_ptr;

public:
  typedef _Tp element_type;

  explicit auto_ptr(_Tp* __p = 0) __STL_NOTHROW : _M_ptr(__p) {}
  auto_ptr(auto_ptr& __a) __STL_NOTHROW : _M_ptr(__a.release()) {}

  template <class _Tp1> auto_ptr(auto_ptr<_Tp1>& __a) __STL_NOTHROW
    : _M_ptr(__a.release()) {}

  auto_ptr& operator=(auto_ptr& __a) __STL_NOTHROW {
    reset(__a.release());
    return *this;
  }

  template <class _Tp1>
  auto_ptr& operator=(auto_ptr<_Tp1>& __a) __STL_NOTHROW {
    reset(__a.release());
    return *this;
  }
  
  ~auto_ptr() { delete _M_ptr; }
 
  _Tp& operator*() const __STL_NOTHROW {
    return *_M_ptr;
  }
  _Tp* operator->() const __STL_NOTHROW {
    return _M_ptr;
  }
  _Tp* get() const __STL_NOTHROW {
    return _M_ptr;
  }
  _Tp* release() __STL_NOTHROW {
    _Tp* __tmp = _M_ptr;
    _M_ptr = 0;
    return __tmp;
  }
  void reset(_Tp* __p = 0) __STL_NOTHROW {
    if (__p != _M_ptr) {
      delete _M_ptr;
      _M_ptr = __p;
    }    
  }

public:
  auto_ptr(auto_ptr_ref<_Tp> __ref) __STL_NOTHROW
    : _M_ptr(__ref._M_ptr) {}

// !!!!!!!!!!
  auto_ptr& operator=(auto_ptr_ref<_Tp> __ref) __STL_NOTHROW {
    if (__ref._M_ptr != this->get()) {
      delete _M_ptr;
      _M_ptr = __ref._M_ptr;
    }
    return *this;
  }
// !!!!!!!!!!

  template <class _Tp1> operator auto_ptr_ref<_Tp1>() __STL_NOTHROW 
    { return auto_ptr_ref<_Tp>(this->release()); }
  template <class _Tp1> operator auto_ptr<_Tp1>() __STL_NOTHROW
    { return auto_ptr<_Tp1>(this->release()); }
};

} // namespace std


Да, компилятор у меня gcc v3.0.3

JekLove
() автор топика

По умолчанию генерится оператор присваивания типа

class b;...;b& operator=(const b&);

В итоге у тебя не определен оператор присваивания для типа который хранится в auto_ptr (присвоение межу объектами типа auto_ptr возможно) и его надо определять явно;))

tvn
()

Но ведь у нас есть оператор
auto_ptr& operator=(auto_ptr& __a),
есть и конструктор auto_ptr(_Tp* __p).
Или я что-то не понимаю?

JekLove
() автор топика

Нет опреатора присваивания для типа котрым управляет auto_ptr

T.е: auto_prt<int*> b;

Нужен оператор: auto_ptr<int*>& operator=(int*)

Где разница в правой части: там не auto_ptr а int *

tvn
()

Что значит - управляет?

JekLove
() автор топика

_Tp* _M_ptr - управляемый тип или объект (называй это как тебе удобнее но мне кажется это наиболее отражающим суть - auto_ptr удалит _M_ptr, значит auto_ptr управляет типом/класом/объектом _Tp* _M_ptr) ;))

tvn
()

А, понял.
Но все-таки мне неясно, ведь конструирование auto_ptr и auto_ptr_ref
по указателю на _Tp одинаково, так почему же для присваивания необходима эта структура (auto_ptr_ref)?

JekLove
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.