std :: auto_ptr становится недействительным после передачи в функцию по значению

У меня есть следующий пример кода:

#include <iostream>
#include <auto_ptr.h>

class A
{
public:
A(){ std::cout << "A ctor" << std::endl;}
~A() {std::cout << "A dtor" << std::endl;}
void bar(){std::cout << "bar()" << std::endl;}
};

void foo(std::auto_ptr<A> a)
{
std::cout << "foo()" << std::endl ;
}

int main()
{
std::auto_ptr<A> a(new A());
a->bar();
return 0;
}

выход:

A ctor
bar()
A dtor

Теперь, если я позвоню foo(a), a будет разрушен перед звонком bar():

int main()
{
std::auto_ptr<A> a(new A());
foo(a);
a->bar();
return 0;
}

выход:

A ctor
foo()
A dtor
bar()

Почему a разрушен после foo() называется?

Еще я не понимаю, что если я передам параметр foo по ссылке, a не будет уничтожен после звонка foo():

void foo(std::auto_ptr<A> &a)
{
std::cout << "foo()" << std::endl ;
}

int main()
{
std::auto_ptr<A> a(new A());
foo(a);
a->bar();
return 0;
}

выход:

A ctor
foo()
bar()
A dtor

Как передача по ссылке влияет на время жизни auto_ptr?

0

Решение

auto_ptr крадет собственность при копировании. Когда вы копируете его, копия теперь содержит указатель на объект, а оригинал ничего не содержит.

Это также устаревшая концепция. Если у вас есть доступ к C ++ 11, используйте unique_ptr вместо.

6

Другие решения

У auto_ptr есть семантика передачи собственности. Если вы передадите его по значению, то владение передается временному объекту, который, конечно, будет уничтожен, когда выйдет из области видимости.

2

Std :: auto_ptr обычно не соответствует ожиданиям людей. Идея заключалась в том, что это более безопасная концепция, поскольку ptr очищается, как только объект выходит из области видимости. Таким образом, ваша «новая А» не будет пропущена даже в случае многократных возвратов / исключений и т. Д.

Однако, как вы показали, также очень легко вызвать нелегальный доступ к памяти, потому что два auto_ptr, совместно использующие один указатель, являются причиной катастрофы.

Если вам нужен только ptr, который вы можете использовать, и не беспокойтесь о выпуске, вы должны использовать unique_ptr. unique_ptr не может быть скопирован. Таким образом, вы можете передать ссылку на нее, но не скопировать ее.

Обычно наиболее полезной конструкцией является shared_ptr, который позволяет нескольким владельцам совместно использовать один и тот же ptr и гарантирует, что он будет освобожден, когда все владельцы выйдут из области видимости.

Все они являются частью стандартной библиотеки c ++ 11 или доступны через библиотеку boost.

1
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector