LINUX.ORG.RU

Непонятки с auto_ptr


0

0

Сижу изачаю стандартную библиотеку С++. Дошел до шаблона auto_ptr<>. Не могу понять для чего нужен вспомогательный класс auto_ptr_ref и связанный с ним преобразования. Более конкретно вот кусок определения шаблона класса auto_ptr<> из заголовка <memory>

template <typename _Tp>
class auto_ptr {
private:
_Tp* _M_ptr;
public:
typedef _Tp element_type;

// все лешнее вырезано :)

auto_ptr(auto_ptr_ref<element_type> __ref) throw()
: _M_ptr(__ref._M_ptr) { }

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

template<typename _Tp1>
operator auto_ptr_ref<_Tp1>() throw()
{ return auto_ptr_ref<_Tp1>(this->release()); }

template<typename _Tp1>
operator auto_ptr<_Tp1>() throw()
{ return auto_ptr<_Tp1>(this->release()); }

}; //конец объявления auto_ptr<>


еще более круто было бы если чья-то свтлая голова написала что происходит при вызове типа:

auto_ptr<int> f();

int main()
{
auto_ptr<int> p = f();
}

я имею ввиду не механизм передачи влядения, а именно какие конструкторы и преобразования вызываются в данной кончтрукции.

Спасибо

anonymous

auto_ptr<int> f();

int main() { auto_ptr<int> p = f(); }

1) auto_ptr<int> конструктор по умолчанию 2) конструктор копирования при возврате из функции f 3) оператор присвоения ( operator = )

mumg
()
Ответ на: комментарий от mumg

> 1) auto_ptr<int> конструктор по умолчанию 2) конструктор копирования при возврате из функции f 3) оператор присвоения ( operator = )

нправда :)

B a;
B b = a; // эквивалентно B b(a);

Еще одна неправда в том, что rvalue нельзя передавать как не константную ссылку, а в классе auto_ptr operator= и конструктор копирования объявлены как:


template <typename T>
auto_ptr {
public:
typedef T element_type;

auto_ptr(auto_ptr& __a) throw();
template <typename T1> auto_ptr(auto_ptr<T1>& __a) throw();

auto_ptr& operator=(auto_ptr& __a) throw();
template <typename T1>
auto_ptr& operator(auto_ptr<T1>& __a) throw();
};


А сей хитрый трюк с auto_ptr_ref сделан для того чтобы как раз можно было возвращать из фунцкции объект auto_ptr. Вернее чтобы им после этого можно было пользоваться.

anonymous
()
Ответ на: комментарий от anonymous

Да, ты прав. Самое интересное что выполняется только один конструктор.

#include <iostream>

#define LOG(Message) std::cout << __LINE__ << ": " << Message << std::endl;

class Test { public: Test (); Test ( const int in_Value ); Test & operator = ( const Test & in_Value ); };

Test::Test() { LOG("Test::Test()"); }

Test::Test( const int in_Value ) { LOG("Test::Test( const int in_Value )"); }

Test & Test::operator = ( const Test & in_Value ) { LOG("Test & operator = ( const Test & in_Value )"); return *this; }

Test func () { return Test(0); }

int main ( const int argc , char ** argv ) { Test test = func(); return 0; }

Результат:

То есть получается что на выходе из функции происходит передача по ссылке а не по значению. Мало того, конструктор копирования для Test test = не вызывается. Может я туплю и спать надо больше ~8-[ 0 ] ./test.x 20: Test::Test( const int in_Value )

mumg
()
Ответ на: комментарий от anonymous

> B a;
> B b = a; // эквивалентно B b(a);

вы же не будете спорить, что это не всегда так? :)
конструктор копирования и оператор присваивания все-таки вещи разные и при [странном] желании могут и не совпадать в поведении..

// wbr

klalafuda ★☆☆
()
Ответ на: комментарий от klalafuda

Я имел ввиду что это эквивалентно только при определении новой переменной как приведенном примере:

B a;
B b = a; // В данном случае это есть B b(a);

В случае когда пеперменная уже создана конечно же используется B& operator=(B const&)

B a;
B b;
b = a; // В данном случае это есть b.operator=(a);

anonymous
()
Ответ на: комментарий от klalafuda

> ..и сильно зря, ибо начальное утверждение было верным.. ;)

Так какое ???

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