Как использовать интеллектуальные указатели С++?

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

Можете ли вы объяснить, какие типы интеллектуальных указателей, как они работают и когда их использовать?

Также, что такое "протокол" при получении или передаче исходных указателей в интерфейсах, написанных другими людьми?

Спасибо.

Ответ 1

С++ 98 не предоставляет никаких интеллектуальных указателей, кроме auto_ptr, чреватых собственными проблемами. С++ 0X пытается исправить это, введя еще несколько разновидностей (shared_ptr, unique_ptr и т.д.). Тем временем лучше всего использовать Boost. Взгляните на различные ароматы, доступные вам здесь. Boost поддерживается сообществом, широко протестирован и, конечно, свободен. Существует отличная документация с примером кода, который поможет вам начать работу.

Можете ли вы объяснить, какие типы интеллектуальных указателей, как они работают и когда их использовать?

Их несколько. Короче говоря:

scoped_ptr <boost/scoped_ptr.hpp>  Простое владение одиночным объекты. Noncopyable.

scoped_array <boost/scoped_array.hpp> Простая подошва владение массивами. Noncopyable.

shared_ptr <boost/shared_ptr.hpp>  Владение объектами несколько указателей.

shared_array  <boost/shared_array.hpp> Массив собственность, распределенная между несколькими указатели.

weak_ptr  <boost/weak_ptr.hpp> Не владеющие наблюдатели объекта, принадлежащего shared_ptr.

intrusive_ptr  <boost/intrusive_ptr.hpp> Общие владение объектами со встроенным счетчик ссылок.

(Это из документации Boost и обратите внимание, что у них есть контейнеры для таких указателей тоже!)

Также, что такое "протокол" при получении или передаче исходных указателей в интерфейсах, написанных другими людьми?

Для меня важны следующие правила:

  • Уст-квалификационная
  • Не освобождать вещи, которые я не выделял
  • Проверка передачи прав собственности/перемещение семантики

Ответ 2

Смарт-указатели - это уровень абстракции для автоматизации процесса выделения и освобождения памяти, их функции-конструктора, получает выделенную память (через указатель) и их деструкторную функцию, освобождает выделенную память. Конечно, конструктор и деструктор могут быть встроены (поэтому для их вызова нет накладных расходов). Например:

{
    int* raw = new int(40);
    auto_ptr<int> sp(raw); //inline constructor: internal_holder = raw
    //...
    //inline destructor: delete internal_holder
}

В С++ полезно использовать указатели косвенно (скрыть их за классами). Накладные расходы на создание нового интеллектуального указателя незначительны. Но shared_ptr более весомый из-за его поведения для подсчета ссылок (это подсчет ссылок).

Когда мы хотим использовать необработанные указатели, полученные от других функций, которые написаны другими людьми, если эти исходные указатели не должны освобождаться самим собой, тогда мы не должны использовать Smart Pointers.

Ответ 3

О STL auto_ptr, я рекомендую прочитать Herb Sutter (автор хороших книг на С++) GuruOfTheWeek: используйте Ссылка

Ответ 4

Нет правила о том, когда использовать интеллектуальные указатели. Более того, вы можете использовать интеллектуальные указатели, где это возможно. Исходные указатели являются редкостью в хорошо написанном коде на С++. Когда вы получаете необработанный указатель, оберните его самонастраивающимся пользовательским письменным умным указателем, если это ваш долг освободить его.

Ответ 5

Завершить ответы и те, которые доступны с помощью следующего стандарта С++ 0x. Эти ссылки приводят примеры того, когда и как они используются. Он также документирует отношения между shared_ptr и weak_ptr.

http://www2.research.att.com/~bs/C++0xFAQ.html#std-shared_ptr

http://www2.research.att.com/~bs/C++0xFAQ.html#std-weak_ptr

http://www2.research.att.com/~bs/C++0xFAQ.html#std-unique_ptr