Умные указатели — случаи, когда они не могут заменить необработанные указатели

HI,

У меня есть этот запрос об умных указателях.

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

может ли кто-нибудь сказать мне, когда и где они не могут заменить необработанные указатели?


person Vijay    schedule 07.04.2010    source источник
comment
Если ваш друг привел аргументацию, он должен был доказать ее хотя бы одним примером. Тем более после того, как ты попросил об этом.   -  person Daniel Daranas    schedule 07.04.2010
comment
@ Даниэль Он должен был доказать это на всех примерах.   -  person Tom    schedule 07.04.2010
comment
Я не мог сказать вам, в каких случаях он не будет использовать интеллектуальный указатель, вероятно, просто не хотел.   -  person Harald Scheirich    schedule 07.04.2010
comment
Я согласен с вашим другом. Но ситуации, в которых нельзя использовать умные указатели, не будут общими, это будут конкретные ситуации, которые вы не сможете придумать заранее. Это как аргумент Все лебеди белые. Они? Покажите мне конкретный экземпляр, где они не белые. (Для европейца это было невозможно доказать ложным). Пока первый европеец не отправился в Австралию и не обнаружил конкретную ситуацию, в которой это было не так.   -  person Martin York    schedule 07.04.2010


Ответы (7)


  1. Передача указателей на устаревшие API.
  2. Обратные ссылки в древовидной структуре с подсчетом ссылок (или в любой циклической ситуации, если на то пошло). Это спорно, так как вы можете использовать слабые ссылки.
  3. Итерация по массиву.

Есть также много случаев, когда вы можете использовать интеллектуальные указатели, но не хотите, например:

  1. Некоторые небольшие программы предназначены для утечки всего, потому что это просто не стоит дополнительной сложности, связанной с выяснением того, как убрать за собой.
  2. Мелкозернистые пакетные алгоритмы, такие как синтаксические анализаторы, могут выделять из заранее выделенного пула памяти, а затем просто сбрасывать весь пул по завершении. Иметь умные указатели в такой пул обычно бессмысленно.
person Marcelo Cantos    schedule 07.04.2010
comment
@ Дэвид, потому что в этом нет смысла, поскольку вы знаете, что не владеете элементами массива (вы просто просматриваете его), и координация с тем, кто владеет массивом, будет очень сложной. Кроме того, это может быть массив, размещенный в стеке, вообще не требующий управления памятью. - person Marcelo Cantos; 07.04.2010
comment
Я считаю, что smart_ptr позволяет перегрузить функцию очистки памяти. Следовательно, вполне возможно, что пул памяти будет прекрасно работать с smart_ptr, если ваша функция очистки правильно скоординирована с вашей функцией создания. - person wheaties; 07.04.2010
comment
Я нахожу 1 и 3 соломенных человечков. На 1 большинство интеллектуальных указателей имеют своего рода get, поэтому вы все равно можете передать содержащийся указатель. А 3 - это даже не та ситуация, которая имеет значение. Это все равно, что сказать 4. Целое число. 5. Поплавок. и т. д. для каждого типа. Это просто не применимо. И 2 решается слабым указателем. - person GManNickG; 07.04.2010
comment
@Marcelo: вопрос заключался в том, что вы не можете сделать с умными указателями, а не в ситуациях, когда умные указатели бесполезны. - person David Thornley; 07.04.2010
comment
@David, @GMan: в этом случае говорить, что вы ничего не можете сделать с необработанным указателем, что вы не можете сделать с умным указателем, потому что умный указатель может возвращать необработанный указатель, и вы можете использовать это, скорее упускает суть ИМО. Наверняка это вопрос о том, для чего нужны необработанные указатели, а не вопрос о том, можно ли умный указатель засунуть в какой-то контекст, где он не поможет. Я уверен, что вы можете, но зачем? - person Steve Jessop; 07.04.2010
comment
@ Дэвид, вопрос был о том, где нельзя заменить необработанные указатели умными указателями. Вы не согласны с моим утверждением о том, что вы не можете заменить необработанные указатели умными указателями в устаревших API? - person Marcelo Cantos; 08.04.2010
comment
@GMan: В 1 тот факт, что вы можете получить необработанный указатель из интеллектуального указателя, не только упускает смысл, но и неверен. Устаревший API может предоставить вам необработанный указатель в середине некоторой структуры, который вы затем должны использовать для доступа к некоторым данным. Вы просто не можете полностью избежать работы с необработанными указателями. На 3 я говорю о цикле таким образом: for (char* c = buf; *c; ++c) ...; это очень распространенная идиома и сложно представить, как можно было бы вообще ввести здесь смарт-пойнтер, не говоря уже о том, зачем. - person Marcelo Cantos; 08.04.2010
comment
@Steve @Marcelo: Тогда я упустил суть вопроса. Если вы каким-то образом получаете указатель и не владеете им, очевидно, что интеллектуальный указатель, который инкапсулирует владение, не применяется. - person GManNickG; 08.04.2010

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

person Community    schedule 07.04.2010

Зависит от умного указателя, который вы используете. std::auto_ptr несовместим с контейнерами STL.

person stonemetal    schedule 07.04.2010

Это вопрос семантики:

  • умный указатель: вы владеете (по крайней мере частично) памятью, на которую указывает, и поэтому несете ответственность за ее освобождение
  • обычный указатель: вам дается дескриптор объекта... или нет (NULL)

Например:

class FooContainer
{
public:
  typedef std::vector<Foo> foos_t;

  foos_t::const_iterator fooById(int id) const; // natural right ?
};

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

class FooContainer
{
public:
  const Foo* fooById(int id) const;
};

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

Конечно, вы также можете использовать здесь weak_ptr (вы получаете метод expired), однако это потребует использования shared_ptr в первую очередь, и вы можете не использовать их в своей реализации.

person Matthieu M.    schedule 07.04.2010

взаимодействие с унаследованным кодом. если API нуждается в необработанном указателе, вам нужно предоставить необработанный указатель, даже если однажды в вашем коде вы завернете его в интеллектуальный указатель.

person jk.    schedule 07.04.2010

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

person Ferruccio    schedule 07.04.2010

Было бы довольно сложно реализовать интеллектуальные указатели, если в какой-то момент вы не используете простые указатели.

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

person UncleBens    schedule 07.04.2010