Почему auto_ptr считается устаревшим?

Я слышал, что auto_ptr устарела в C ++ 11. В чем причина этого?

Также мне хотелось бы узнать разницу между auto_ptr и shared_ptr.

78 голосов | спросил brett 13 thEurope/Moscowp30Europe/Moscow09bEurope/MoscowMon, 13 Sep 2010 07:23:48 +0400 2010, 07:23:48

5 ответов


0

Прямая замена auto_ptr (или в любом случае ближе всего к нему) - это unique_ptr . Что касается «проблемы», то все довольно просто: auto_ptr передает право собственности, когда оно назначено. unique_ptr также передает право собственности, но благодаря кодификации семантики перемещения и магии ссылок на rvalue это может сделать это значительно естественнее. Он также значительно лучше подходит для остальной части стандартной библиотеки (хотя, честно говоря, отчасти это происходит благодаря тому, что остальная часть библиотеки изменилась, чтобы приспособить семантику перемещения вместо того, чтобы всегда требовать копирования).

Изменение имени (IMO) также приветствуется - auto_ptr на самом деле мало что говорит о том, что оно пытается для автоматизации, тогда как unique_ptr является довольно разумным (если кратко) описанием того, что предоставляется.

ответил Jerry Coffin 13 thEurope/Moscowp30Europe/Moscow09bEurope/MoscowMon, 13 Sep 2010 07:45:22 +0400 2010, 07:45:22
0

Я нашел отличные ответы, но с точки зрения указателей. ИМО, идеальный ответ должен иметь перспективный ответ пользователя /программиста.

Первым делом первым (как указал Джерри Коффин в своем ответе)

  • auto_ptr может быть заменен shared_ptr или unique_ptr в зависимости от ситуации

shared_ptr: Если вас беспокоит освобождение ресурса /памяти И если у вас есть более одной функции, которая может использовать объект AT-DIFFERENT раз, то перейдите к shared_ptr.

В DIFFERENT-Times, представьте себе ситуацию, когда object-ptr хранится в нескольких структурах данных, а затем к ним обращаются. Несколько потоков, конечно, еще один пример.

unique_ptr: Если все, что вас беспокоит, это освобождение памяти и доступ к объекту SEQUENTIAL, то перейдите к unique_ptr.

Под SEQUENTIAL я имею в виду, что в любой момент объект будет доступен из одного контекста. Например. объект, который был создан и использован сразу после создания создателем. После создания объект сохраняется в FIRST структуре данных. Затем либо объект уничтожается после ОДНОЙ структуры данных, либо перемещается в SECOND структуру данных.

В этой строке я буду называть общий /уникальный _ptr умными указателями. (auto_ptr также является умным указателем, НО из-за недостатков в его дизайне, для которых они устарели, и которые, я думаю, я укажу в следующих строках, они не должны группироваться с умным указателем.)

  

Самая важная причина того, почему auto_ptr устарел в пользу смарт-указателя,    присваивание-семантика Если бы не по этой причине, они добавили бы все новые плюсы семантики перемещения в auto_ptr вместо того, чтобы осудить его. Так как семантика присваивания была наиболее неприязненной функцией, они хотели, чтобы эта функция исчезла, но поскольку написан код, использующий эту семантику (который комитет по стандартам не может изменить), им пришлось отказаться от auto_ptr вместо модифицируя его.

По ссылке: http://www.cplusplus.com/reference/память /unique_ptr /оператор = /

Вид назначений, поддерживаемый unqiue_ptr

  • задание на перемещение (1)
  • назначить нулевой указатель (2)
  • назначение приведения типа (3)
  • копировать назначение (удалено!) (4)

От: http://www.cplusplus.com/reference/memory/auto_ptr /оператор = /

Вид назначений, поддерживаемых auto_ptr

  • копировать задание (4) виновник

Теперь, рассуждая о том, ПОЧЕМУ само назначение копии было настолько неприязненным, у меня есть эта теория:

  1. Не все программисты читают книги или стандарты
  2. auto_ptr, на первый взгляд, обещает вам право собственности на объект
  3. предложение little- * (каламбур), auto_ptr, которое не читается всеми программистами, позволяет присваивать один auto_ptr другому и передавать владение.
  4. Исследования показали, что это поведение предназначено для 3,1415926535% всех случаев использования и непреднамеренно в других случаях.

Непреднамеренное поведение действительно не нравится и, следовательно, неприязнь к auto_ptr.

(Для 3.1415926536% программистов, которые намеренно хотят передать право владения C ++ 11, предоставили им std :: move (), что сделало их намерение кристально ясным для всех интернов, которые собираются читать и поддерживать код. )

ответил Ajeet Ganga 24 FebruaryEurope/MoscowbSun, 24 Feb 2013 10:12:35 +0400000000amSun, 24 Feb 2013 10:12:35 +040013 2013, 10:12:35
0

shared_ptr можно хранить внутри контейнеров. auto_ptr невозможно.

Кстати, unique_ptr действительно является прямым auto_ptr

ответил Ben Voigt 13 thEurope/Moscowp30Europe/Moscow09bEurope/MoscowMon, 13 Sep 2010 07:27:21 +0400 2010, 07:27:21
0

Еще одна попытка объяснить разницу ....

Функционально, std::unique_ptr в C ++ 11 является «фиксированным» std::auto_ptr: оба они подходят, когда - в любой момент времени во время выполнения - должен быть один владелец умного указателя для объекта, на который указывает указатель.

Принципиальное отличие заключается в создании копии или присвоении из другого не истекающего интеллектуального указателя, показанного в строках => ниже:

   std::auto_ptr<T> ap(...);
   std::auto_ptr<T> ap2(get_ap_to_T());   // take expiring ownership
=> std::auto_ptr<T> ap3(ap);  // take un-expiring ownership ala ap3(ap.release());
   ap->xyz;  // oops... can still try to use ap, expecting it to be non-NULL

   std::unique_ptr<T> up(...);
   std::unique_ptr<T> up2(get_up_to_T());   // take expiring ownership
=> std::unique_ptr<T> up3(up);  // COMPILE ERROR: can't take un-expiring ownership
=> std::unique_ptr<T> up4(std::move(up));  // EXPLICIT code allowed
=> std::unique_ptr<T> up4(up.release());   // EXPLICIT code allowed

Выше ap3 незаметно «крадет» право собственности на *ap, оставив ap равным nullptr, и проблема в том, что это может произойти слишком легко, без необходимости продумывать программист.

Например, если class /struct имеет член std::auto_ptr, тогда создание копии экземпляра приведет к release указатель от копируемого экземпляра: это странно и опасно запутывает семантику, поскольку обычно копирование чего-либо не изменяет его. Для автора класса /структуры легко пропустить освобождение указателя при рассуждении об инвариантах и ​​состоянии и, следовательно, случайно попытаться разыменовать смарт-указатель, когда он нулевой, или просто не имеют ожидаемого доступа /владения указанными данными.

ответил Tony Delroy 12 FebruaryEurope/MoscowbThu, 12 Feb 2015 07:21:34 +0300000000amThu, 12 Feb 2015 07:21:34 +030015 2015, 07:21:34
0

auto_ptr нельзя использовать в контейнерах STL, поскольку он имеет конструктор копирования, который не соответствует требованиям контейнера CopyConstructible . unique_ptr не реализует конструктор копирования, поэтому контейнеры используют альтернативные методы. unique_ptr может использоваться в контейнерах и быстрее для алгоритмов std, чем shared_ptr.

#include <iostream>
#include <type_traits>
#include <vector>
#include <memory>

using namespace std;

int main() {
  cout << boolalpha;
  cout << "is_copy_constructible:" << endl;
  cout << "auto_ptr: " << is_copy_constructible< auto_ptr<int> >::value << endl;
  cout << "unique_ptr: " << is_copy_constructible< unique_ptr<int> >::value << endl;
  cout << "shared_ptr: " << is_copy_constructible< shared_ptr<int> >::value << endl;

  vector<int> i_v;
  i_v.push_back(1);
  cout << "i_v=" << i_v[0] << endl;
  vector<int> i_v2=i_v;
  cout << "i_v2=" << i_v2[0] << endl;

  vector< unique_ptr<int> > u_v;
  u_v.push_back(unique_ptr<int>(new int(2)));
  cout << "u_v=" << *u_v[0] << endl;
  //vector< unique_ptr<int> > u_v2=u_v;  //will not compile, need is_copy_constructible == true
  vector< unique_ptr<int> > u_v2 =std::move(u_v);  // but can be moved
  cout << "u_v2=" << *u_v2[0] << " length u_v: " <<u_v.size() << endl;

  vector< shared_ptr<int> > s_v;
  shared_ptr<int> s(new int(3));
  s_v.push_back(s);
  cout << "s_v=" << *s_v[0] << endl;
  vector< shared_ptr<int> > s_v2=s_v;
  cout << "s_v2=" << *s_v2[0] << endl;

  vector< auto_ptr<int> > a_v;  //USAGE ERROR

  return 0;
}

>cxx test1.cpp -o test1
test1.cpp: In function âint main()â:
test1.cpp:33:11: warning: âauto_ptrâ is deprecated (declared at /apps/hermes/sw/gcc/gcc-4.8.5/include/c++/4.8.5/backward/auto_ptr.h:87) [-Wdeprecated-declarations]
   vector< auto_ptr<int> > a_v;  //USAGE ERROR
           ^
>./test1
is_copy_constructible:
auto_ptr: false
unique_ptr: false
shared_ptr: true
i_v=1
i_v2=1
u_v=2
s_v=3
s_v2=3
ответил edW 11 J000000Monday16 2016, 22:02:50

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132