Здравствуйте, Аноним, Вы писали:
А>В коде приведенном ниже программа почему-то падает в случае (2). А>Просто фантастика, не могу понять почему... Уже день за отладчиком провел...
А>Помогите, пожалуйста...
Здравствуйте, Smal, Вы писали:
S>...
S>А оператор = кто будет переопределять?
Есть конструктор копирования. Оператор = не нужен в данном случае.
S>К тому же, этот код компилиться не будет. Метод reset не константный.
Приведенный код БУДЕТ компилироваться, пока этот шаблонный метод не будет использован (т.е. по всем правилам метод инстанцируется только в случае его использования).
Здравствуйте, Аноним, Вы писали:
А>Приведенный код БУДЕТ компилироваться, пока этот шаблонный метод не будет использован (т.е. по всем правилам метод инстанцируется только в случае его использования).
Да, сорри, я имел в виду, что const в шаблонном методе конечно же был лишний, но тем не менее код скомпилируется
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, Smal, Вы писали:
S>>...
S>>А оператор = кто будет переопределять?
А>Есть конструктор копирования. Оператор = не нужен в данном случае.
S>>К тому же, этот код компилиться не будет. Метод reset не константный.
А>Приведенный код БУДЕТ компилироваться, пока этот шаблонный метод не будет использован (т.е. по всем правилам метод инстанцируется только в случае его использования).
Списибо, это я знаю. Только смысл писать код, который инстанцироваться не будет?
Проблема в том, что оператор = должен иметь такую же сигнатуру, т.е. принимать параметр
по константной ссылке (иначе нельзя будет использовать возвращаемое значение из функции).
Это возможно при использовании микрософтовских фич (VS c включенными фичами позволяет передавать
временный объект по не константной ссылке), но не в рамках стандарта. Для того, что бы решить
эту проблему придумали auto_ptr_ref.
А>Приведенный код БУДЕТ компилироваться, пока этот шаблонный метод не будет использован (т.е. по всем правилам метод инстанцируется только в случае его использования).
а что у тебя происходит в
e = Gr::someOperation(15, 10)
ты представляешь?
Of course, the code must be complete enough to compile and link.
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, Smal, Вы писали:
S>>...
S>>А оператор = кто будет переопределять?
А>Есть конструктор копирования. Оператор = не нужен в данном случае.
Не правда.
T a; // конструктор по умолчанию
T b = a; // конструктор копирования
a = b; // оператор =
не конструктор копирования. Компилятор неявно сгенерит конструктор копирования, что-то вроде:
weak_ptr(const weak_ptr<T> &); //тот же T, которым ты параметризовал свой класс, он будет просто почленно копировать и reset вызван не будет (да и зачем он тебе, если это weak_ptr????).
Вообще, глядя на твой код трудно понять, что ты хочешь. Хинт в e = Gr::someOperation(15, 10) будет временный объект, деструктор которого освободит память, к которой ты обратишься потом в e->type().
Of course, the code must be complete enough to compile and link.
Здравствуйте, Smal, Вы писали:
S>Здравствуйте, Аноним, Вы писали:
А>>Здравствуйте, Smal, Вы писали:
S>>>...
S>>>А оператор = кто будет переопределять?
А>>Есть конструктор копирования. Оператор = не нужен в данном случае. S>Не правда.
S>
S>T a; // конструктор по умолчанию
S>T b = a; // конструктор копирования
S>a = b; // оператор =
S>
S>В твоем случае вызывается именно оператор =.
OK. (кстати, я знаю про auto_ptr — но мне нужно разобраться в частном weak_ptr)
видоизменяем код Gr::weak_ptr так:
(добавили operator =, удалили const в конструкторе копирования)
template<typename T>
class weak_ptr
{
public:
weak_ptr( T * p = 0 )
: mp( p )
{}
template<typename U>
weak_ptr( weak_ptr<U>& wp )
{
mp = wp.mp;
wp.reset();
}
template<typename U>
weak_ptr( U * p )
: mp( p )
{
}
~weak_ptr()
{ reset(); }
void reset( T * p = 0 )
{
if( mp != 0 )
delete mp;
mp = p;
}
operator bool () const
{
return mp != 0;
}
template<typename U>
weak_ptr operator = ( const weak_ptr<U>& rhs )
{
mp = rhs.mp;
rhs.reset();
return *this;
}
T * operator -> () const
{
assert( mp != 0 );
return mp;
}
private:
T * mp;
}; // class weak_ptr
L_L>Вообще, глядя на твой код трудно понять, что ты хочешь. Хинт в e = Gr::someOperation(15, 10) будет временный объект, деструктор которого освободит память, к которой ты обратишься потом в e->type().
Здравствуйте, StevenIvanov, Вы писали:
SI>Почему баг не исчезает?
А теперь вспомним, что конструктор копирования и оператор = для
того же класса не должен быть шаблоном. %)
У тебя operator= даже не инстанциируется, т.к. используется сгенеренный компилятором.
Кроме шаблонности он еще и написан не совсем правильно — вызывает reset() а тот соответственно delete...
S>А теперь вспомним, что конструктор копирования и оператор = для S>того же класса не должен быть шаблоном. %) S>У тебя operator= даже не инстанциируется, т.к. используется сгенеренный компилятором.