Здравствуйте, NightWind, Вы писали:
NW>Приведите, пожалуйста, пример, который перестаёт компилироваться (работать) если этот метод убрать.
class A {
// ...public:
virtual ~A() {}
};
class B : public A {
// ...
};
std::auto_ptr<B> foo();
inline std::auto_ptr<A> bar()
{
return foo();
}
NW>Заранее благодарен.
Для спасибо тут есть кнопки...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
NW>Приведите, пожалуйста, пример, который перестаёт компилироваться (работать) если этот метод убрать. NW>Заранее благодарен.
На счет примера, трудно предложить, а идея этого оператора, достаточна проста, если обрать внимание, то очень многие классы STL изобилуют в той или иной мере такой конструкцией, в шаблонных классах заложена архитектура автоматической специализации если в качеcтве приемника или источника выступает близкий по сигнатуре класс, например был изначально std::auto_ptr<int> а мы его присвоим std::auto_ptr<long>, для нас разницы нет, для компилятора разница сушественная, если потребитель кода будет специализировать класс, например
template<> auto_ptr<long> auto_ptr<int>::operator auto_ptr<long>()
...
в этом случае он сможете определить особенное поведение класса auto_ptr для особенных случаев
Здравствуйте, igna, Вы писали:
I>Здравствуйте, dmitry.maystrenco, Вы писали:
DM>>например был изначально std::auto_ptr<int> а мы его присвоим std::auto_ptr<long>
I>Ты не ошибся? Присвоить указатель на int указалю на long?
Выбор int и long не самый удачный, по крайней мере в auto_ptr, для auto_ptr, прокатит без проблем в том случае если классы используемые в параметрах являются элементами в иерархии, причем только с верху вниз, из-за того, что в конструкторе копирования используется присвоение одного указателя другому (настоящих)
class A
{
};
class B : public A
{
};
...
std::auto_ptr<B> b(new B);
std::auto_ptr<A> a = b;
работает, тогда как
std::auto_ptr<A> a(new A);
std::auto_ptr<B> b = a;
уже нет.
Забавно другое, если написать по аналогии с auto_ptr, реализацию:
template<typename _Ty> class A
{
public:
template<typename _Other> A(_Other& _Right)
{
printf("A normal\n");
}
};
class B
{
};
template<> template<> A<long>::A(B& _Right)
{
printf("A special for B\n");
}
то при
double d;
B b;
A<int> a(d);
A<long> c(b);
получаем такой вывод:
A normal
A special for B
и возвращаясь к auto_ptr если попытаться специализировать
то компайлер упорно не видит специализации в данном случае, вот в чем прикол.
а на счет int* к long*, это своеобразно, но не так страшно (под AI32 мы ничего страшного не пытались делать )
Здравствуйте, NightWind, Вы писали:
NW>Да я эти ссылки видел, на них Мейерс в своей статье ссылается.
NW>Меня же совсем другое интересует: Зачем там всё таки последний метод?
Ну так там ведь написано? Дефект 84 (здесь), давал возможность использования двух пользовательских преобразований при инициализации копированием. Это позволяло, в частности, компилировать пример, приведенный Erop-ом. Некоторые компиляторы до сих пор позволяют это делать — VC7.1, например, компилирует тот пример, и выдает только предупреждение:
warning C4927: illegal conversion; more than one user-defined conversion has been implicitly applied while calling the constructor
Здравствуйте, Bell, Вы писали:
B>Ну так там ведь написано? Дефект 84 (здесь), давал возможность использования двух пользовательских преобразований при инициализации копированием.
Наверное самое важное, что без этого оператора компилировался бы следующий очень опасный код:
#include<memory>
struct B {};
struct D: B{};
void f( const std::auto_ptr<B> & )
{
//...
}
int main()
{
std::auto_ptr<B> pB ( new D );
std::auto_ptr<D> pD ( new D );
f( pB );
//здесь pB жив и здоров
f( pD );
//здесь pD будет уничтожен!return 0;
}