Блин, ничего мне не понятно. Такой я тупой.
Вопрос звучал так: почему для присваивания типа
auto_ptr<T> my;
my = new T;
необходим оператор присваивания, принимающий структуру
auto_ptr_ref, если и она и сам auto_ptr конструируются
одинаково из T*?
Блин, ничего мне не понятно. Такой я тупой.
Вопрос звучал так: почему для присваивания типа
auto_ptr<T> my;
my = new T;
необходим оператор присваивания, принимающий структуру
auto_ptr_ref, если и она и сам auto_ptr конструируются
одинаково из T*?
Блин, ничего мне не понятно. Такой я тупой.
Вопрос звучал так: почему для присваивания типа
auto_ptr<T> my;
my = new T;
необходим оператор присваивания, принимающий структуру
auto_ptr_ref, если и она и сам auto_ptr конструируются
одинаково из T*?
A=B значит A.operator=(B), ну и возможно неявные преобразования типов.
A a=B; значит a.A(B) то-есть a конструируется из B, как и в A a(B);
ключевое слово explicit значит что конструктор не учавствует в неявных преобразованиях
и его нужно явно указывать, напр auto_ptr<int> ap(new int(0xff));
далее, у auto_ptr есть конструктор из указателя, из auto_ptr_ref, копирующий конструктор, оператор
присваивания из auto_ptr, и операторы преобразования типа в auto_ptr_ref и в auto_ptr для другого параметра шаблона.
в итоге, auto_ptr<T>::operator=(T*) нету, видимо так и задумывалось,
чтобы только явно их конструировать и потом передавать/присваивать с передачей
"ответственности" за удаление объекта,
когда ты делаешь my = new T; нужного оператора нет
правильное использование auto_ptr<T> my(new T);
потом можно использовать как указатель
Хокей, я понял. Т.е. вроде как мешает explicit, да?
(Я прекрасно знаю, что он значит)
Интересно, что если это слово убрать, ничегошеньки
не изменится... хех.
Пожалуйста.
Код такой:
auto_ptr<int> t;
t = new int;
(Я удалил в auto_ptr все методы, связанные со структурой
auto_ptr_ref и саму эту структуру и, конечно, explicit)
p.cc: In function `int main()':
p.cc:14: no match for `auto_ptr<int>& = int*' operator
mem.h:25: candidates are: auto_ptr<_Tp>&
auto_ptr<_Tp>::operator=(auto_ptr<_Tp>&) [with _Tp = int]
Эх, черт, у меня нет gcc более старой версии :(( Может, кто проверит на
стареньком эту фишку?
Хотя в коде класса auto_ptr перед тем оператором присваивания, принимающим структуру auto_ptr_ref, имеется очень интересный комментарий:
// According to the C++ standard, these conversions are required. Most
// present-day compilers, however, do not enforce that equirement---and,
// in fact, most present-day compilers do not support the language
// features that these conversions rely on.
Что бы это значило??
#include "memory.h"
auto_ptr<int> my(new int);
my=new int;
если без explicit то: g++ --version; g++ -W -Wall -c auto_ptr.cc
2.95.4
auto_ptr.cc: In function `int main()':
auto_ptr.cc:9: initialization of non-const reference type `class auto_ptr<int> &'
auto_ptr.cc:9: from rvalue of type `auto_ptr<int>'
memory.h:25: in passing argument 1 of `auto_ptr<int>::operator =(auto_ptr<int> &)'
если с explicit то:
auto_ptr.cc: In function `int main()':
auto_ptr.cc:9: no match for `auto_ptr<int> & = T *&'
memory.h:25: candidates are: class auto_ptr<int> & auto_ptr<int>::operator =(auto_ptr<int> &)
две большие разницы.
есть конструкторы
explicit auto_ptr(T*);
auto_ptr(auto_ptr&); //важно, что НЕ const auto_ptr&
есть оператор "передачи ответственности"
auto_ptr& operator=(auto_ptr<T1>&);
если мы пишем что-то вроде
auto_ptr<T> ap;
ap=new T;
нам нужно неявно создать временный объект auto_ptr<T>,
конструктор explicit auto_ptr(T*) не рассматривается,
т.к. explicit.
если убираем explicit, то он принимается во внимание,
но gcc не хочет передавать этот временный объект по
неконстантной ссылке. мол типа как-то странно передавать
временный объект в функцию/оператор который его намеренно
модифицирует, значит полагается на результат изменения
так вот, скачал, собрал gcc-3.0.4, результаты:
#include <iostream>
#include <iomanip>
#include <memory.h>
int main(void)
{
typedef int T;
std::auto_ptr<T> my(new T(1));
T* p=new T(11);
my=p;
my=new T(111);
std::cout << " " << *my << std::endl;
return 0;
}
странно наверное, но все работает :)
export CC=/usr/local/bin/gcc
export LD_LIBRARY_PATH=/usr/local/lib
$CC -W -Wall auto_ptr.cc -lstdc++
ни ошибок ни предупреждений...
почему 2.95.x себя ведет так, как я написал выше --- вопрос,
будем думать...
теперь надеюсь все понятно? :) если нет --- пиши
HTH