Интеллектуальные указатели (самомоднейшее C++)
В современных программирования C++, включает стандартную библиотеку смарт-указатели, которые используются для обеспечения программ, могут свободно памяти и утечки ресурсов и безопасных исключений.
Использование смарт-указатели
Смарт-указатели, определены в std пространство имен в <memory> файл заголовка.Они имеют решающее значение для RAII или Initialialization является приобретение ресурсов идиом программирования.Основной целью данный идиом является убедитесь в том, что приобретение ресурсов происходит в то же время, инициализированный объект таким образом, все ресурсы объекта создаются и подготовить в одной строке кода.На практике основной принцип RAII — предоставить владельцем всех ресурсов, выделенных в куче — например, динамического выделения памяти или системных дескрипторов объектов — объект выделен стек, деструктор которого содержит код для удаления или освобождения ресурса, а также любой связанный код очистки.
В большинстве случаев при инициализации raw маркер указателя или ресурсов на текущий ресурс передайте указатель смарт-указатель, немедленно.В современных C++ необработанных указателей используются только в блоках кода ограниченную область, циклы и вспомогательные функции где важна производительность и никаким путаницы о владении.
В следующем примере сравниваются объявления raw указателя для объявления указателей.
void UseRawPointer()
{
// Using a raw pointer -- not recommended.
Song* pSong = new Song(L"Nothing on You", L"Bruno Mars");
// Use pSong...
// Don't forget to delete!
delete pSong;
}
void UseSmartPointer()
{
// Declare a smart pointer on stack and pass it the raw pointer.
unique_ptr<Song> song2(new Song(L"Nothing on You", L"Bruno Mars"));
// Use song2...
wstring s = song2->duration_;
//...
} // song2 is deleted automatically here.
Как показано в примере смарт-указатель, является класс шаблона, который объявляется в стеке и инициализировать с помощью raw указатель, указывающий на объект выделения кучи.После инициализации смарт-указатель владеет raw указателя.Это означает, что смарт-указатель отвечает за удаление указывает исходный указатель памяти.Деструктор смарт-указатель содержит запрос на удаление, и поскольку смарт-указатель объявлен в стеке, его деструктора вызывается, когда смарт-указатель выходит за область действия, даже если где-нибудь дальнейшей вверх по стеку, выбрасывается исключение.
Доступ инкапсулированные указателя с помощью операторов знакомые указатель -> и *, перегружающий класса смарт-указатель возвращает инкапсулированное raw указатель.
Идиома смарт-указатель C++ напоминает создание объекта в языках, таких как C#: создать объект и подождите, пока система заботу удаление в нужное время.Разница заключается в том, что нет отдельного сборщика мусора выполняется в фоновом режиме; памяти осуществляется с помощью стандарта C++ областей правил таким образом, среде выполнения быстрее и эффективнее.
![]() |
---|
Всегда создайте смарт-указатели на отдельной строке кода, никогда не в список параметров, утечка ресурсами не будет возникать из-за определенных правил распределения списка параметров. |
В следующем примере показано как unique_ptr смарт-указатель типа из библиотеки стандартных шаблонов может использоваться для инкапсуляции указатель для больших объектов.
class LargeObject
{
public:
void DoSomething(){}
};
void ProcessLargeObject(const LargeObject& lo){}
void SmartPointerDemo()
{
// Create the object and pass it to a smart pointer
std::unique_ptr<LargeObject> pLarge(new LargeObject());
//Call a method on the object
pLarge->DoSomething();
// Pass a reference to a method.
ProcessLargeObject(*pLarge);
} //pLarge is deleted automatically when function block goes out of scope.
В примере демонстрируются следующие важные шаги использования смарт-указатели.
Объявите смарт-указатель как автоматический (local).(Не используйте new или malloc выражения на смарт-сам указатель.)
В параметр типа укажите тип, на который указывает на инкапсулированные указателя.
Передать исходный указатель new-ed объекта в конструкторе интеллектуального указателя.(Некоторые функции программы или смарт-указатель, конструкторы это сделать для вас).
Используйте перегруженный -> и * операторы для доступа к объекту.
Позволяет удалить объект смарт-указатель.
Смарт-указатели предназначены быть предельно эффективными так памяти и производительности.Например, элемент данных только в unique_ptr является инкапсулированным указателя.Это означает, что unique_ptr того же размера, как этот указатель байтов четыре или восемь байт.К инкапсулированным указателя с помощью смарт-указатель, перегруженные *-> операторы не значительно медленнее, чем непосредственный доступ к необработанным указатели.
Смарт-указатели имеют свои собственные функции-члены, к которым можно получить с помощью нотации «точка».Например некоторые смарт-указатели STL имеют функцию-член reset, освобождает владельца указателя.Это полезно, когда требуется освободить память, принадлежащие смарт-указатель перед смарт-указатель выходит за область действия, как показано в следующем примере.
void SmartPointerDemo2()
{
// Create the object and pass it to a smart pointer
std::unique_ptr<LargeObject> pLarge(new LargeObject());
//Call a method on the object
pLarge->DoSomething();
// Free the memory before we exit function block.
pLarge.reset();
// Do some other work...
}
Смарт-указатели обычно предоставляют возможность непосредственного доступа к их исходному указателю.Смарт-указатели STL у get функции-члена для этой цели и CComPtr имеет открытый p член класса.Предоставляя прямой доступ к базовым указателя, можно использовать смарт-указатель для управления памятью в коде и передавать исходный указатель на код, который не поддерживает смарт-указатели.
void SmartPointerDemo4()
{
// Create the object and pass it to a smart pointer
std::unique_ptr<LargeObject> pLarge(new LargeObject());
//Call a method on the object
pLarge->DoSomething();
// Pass raw pointer to a legacy API
LegacyLargeObjectFunction(pLarge.get());
}
Виды смарт-указатели
В следующем разделе перечислены различные виды смарт-указатели, которые доступны в среде программирования Windows и описание их использования.
Стандарт C++ библиотека смарт-указатели
Используйте эти смарт-указатели как первый вариант для инкапсуляции указатели на обычные старые объекты C++ (POCO).unique_ptr
Позволяет точно один владелец базового указателя.Использовать в качестве элемента по умолчанию POCO не известно то, что требуется, shared_ptr.Могут быть перемещены в новый владелец, но не копируются или совместно.Заменяет auto_ptr, который является устаревшим.Сравнение с boost::scoped_ptr.unique_ptrявляется небольшим и эффективным; размер составляет один указатель и поддерживает rvalue ссылки для быстрой вставки и извлечения из коллекции библиотеки STL.Файл заголовка: <memory>.Дополнительные сведения см. в разделах Практическое руководство. Создание и использование экземпляров unique_ptr и unique_ptr Class.shared_ptr
Со счетчиком ссылок смарт-указатель.Следует использовать, когда нужно назначить один исходный указатель нескольких владельцев, например, когда возвращать копию указатель из контейнера, но сохранить исходное.Исходный указатель не удаляется до всех shared_ptr владельцев выходе за пределы области действия или в противном случае заданные настройки владельца.Имеет размер двух указателей; один объект и блок общий элемент управления, который содержит счетчик ссылок.Файл заголовка: <memory>.Дополнительные сведения см. в разделах Практическое руководство. Создание и использование экземпляров shared_ptr и shared_ptr Class.weak_ptr
Особой смарт-указатель для использования в сочетании с shared_ptr.A weak_ptr предоставляет доступ к объекту, который владеет одним или несколькими shared_ptr экземпляров, но не участвует в подсчет ссылок.Используется, когда необходимо наблюдать за объектом, но не требуют его оставаться в активном состоянии.Требуется в некоторых случаях прерывание циклических ссылок между shared_ptr экземпляры.Файл заголовка: <memory>.Дополнительные сведения см. в разделах Практическое руководство. Создание и использование экземпляров weak_ptr и weak_ptr Class.
Смарт-указатели для COM-объектов (классический Windows программирование)
При работе с COM-объектами, перенос указателей интерфейса смарт-указатель, соответствующего типа.Active Template Library (ATL) определяет несколько смарт-указатели для различных целей.Можно также использовать _com_ptr_t тип смарт-указатель, который компилятор использует при создании классов-оболочек из TLB-файлов.Это лучший выбор, когда не требуется включать файлы заголовков ATL.Класс CComPtr
Используется, если невозможно использовать библиотеку ATL.Выполняет с помощью подсчета ссылок AddRef и Release методов.Дополнительные сведения см. в разделе Практическое руководство. Создание и использование экземпляров CComPtr и CComQIPtr.Класс CComQIPtr
Похож на CComPtr , но также предоставляет упрощенный синтаксис для вызова QueryInterface на COM-объектов.Дополнительные сведения см. в разделе Практическое руководство. Создание и использование экземпляров CComPtr и CComQIPtr.Класс CComHeapPtr
Смарт-указатель на объекты, которые используют CoTaskMemFree для освобождения памяти.Класс CComGITPtr
Смарт-указатель для интерфейсов, которые получены из таблицы глобального интерфейса (GIT).Класс _com_ptr_t
Похож на CComQIPtr в функции, но не зависит от заголовков ATL.
Смарт-указатели ATL POCO объектов
В дополнение к смарт-указатели для COM-объектов ATL также определяет смарт-указатели и коллекций смарт-указатели для обычного старые объекты C++.В классической программирования для Windows, эти типы являются полезной альтернативой коллекциях STL особенно когда переноса кода не требуется или необходимо смешать модели программирования, STL и ATL.Класс CAutoPtr
Смарт-указатель, который обеспечивает уникальное владения, передача прав владения на копию.Сравним с устаревшей std::auto_ptr класса.Класс CHeapPtr
Смарт-указатель для объектов, которые выдаются с помощью c malloc функции.Класс CAutoVectorPtr
Смарт-указатель для массивов, выделенной с помощью new[].Класс CAutoPtrArray
Класс, инкапсулирующий массив CAutoPtr элементов.Класс CAutoPtrList
Класс, который инкапсулирует методы управления список CAutoPtr узлов.
См. также
Другие ресурсы
Добро пожаловать в C++ (современные C++)