2015-10-14 2 views
1

Насколько я понимаю интеллектуальные указатели, они существуют, чтобы избежать утечек памяти между прочим. Однако часто есть объекты, которые также необходимо освободить, но не на free или delete. Есть ли общий способ использования таких указателей с шаблоном?Обтекание освобождаемого объекта умным указателем

Приводится пример FILE, который должен использовать fclose, когда это будет сделано. Конечно, есть и другие указатели с уникальными функциями релиза. Так что я должен реализовать отдельные оболочки для учета их индивидуального метода выпуска или есть лучший способ сделать это?

Что-то, что может быть использовано как это:

smart_ptr<FILE, fclose> fl = fopen(); 
smart_ptr<IStream, T->Release> pFileStream = SHCreateStreamOnFile(...); 
+0

Да, интеллектуальные указатели в стандартной библиотеке принимают пользовательские функции выпуска. –

ответ

1

Если вы используете unique_ptr или shared_ptr, вы можете указать свой пользовательский деаэратор. Deleter для unique_ptr передается в качестве параметра шаблона, а

Deleter должен быть функциональным объект или именующей ссылка на функциональный объект или именующую ссылку на функцию, вызываемый с аргументом типа unique_ptr<T, Deleter>::pointer

Для самых shated_ptr, в качестве параметра конструктора должен быть указан делектор.

class Foo 
{ 

}; 

class Deleter 
{ 
public: 
    void operator()(Foo *) 
    { 
     std::cout << "deleter"; 
    } 
}; 

int main() { 
    std::unique_ptr<Foo, Deleter> ptr(new Foo()); 
    std::shared_ptr<Foo> ptr1(new Foo(), 
          [](Foo*){std::cout << "deleter for shared_ptr";} 
          ); 
} 

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

+0

Но это все равно означает, что я должен написать индивидуальный дебетер для каждого типа объектов, не так ли? – Devolus

+0

@Devolus, да, для каждого типа объектов, которым требуется конкретное лечение. – SingerOfTheFall

+0

Хорошо. Я надеялся обойти это, возможно, используя умный шаблон или такой, предоставляя метод и не беспокоясь об этом. :) – Devolus

0

Оба shared_ptr и unique_ptr обеспечивают этот объект.


Для shared_ptr, конструктор представляет собой шаблон:

Дополнительный Deleter д может поставляться, что в дальнейшем используется, чтобы уничтожить объект, когда никакие shared_ptr объекты не владеет. По умолчанию в качестве дебетера используется выражение-выражение для типа Y.

В этом случае Deleter может быть любым отозвано, копирования конструктивнозначения, которые получают тип стертых к вызываемому.

Для unique_ptr, типа Deleter является параметром типа самого указателя:

template< 
    class T, 
    class Deleter = std::default_delete<T> 
> class unique_ptr; 

Там нет стирания в этом случае, и Deleter предоставляется с-водником или сброс фактически совпадает с тип ликвидатора.

0

Вы можете построить как shared_ptr (подпись № 3 here), так и unique_ptr (подпись №2 here) с пользовательскими удалениями.

using T = ...; 
auto deleter = [](T* x) { delete x; }; 

// different deleter - different unique_ptr type 
// deleter is stored inline 
auto x = std::unique_ptr<T, decltype(deleter)>(new T(...), deleter); 

// same shared_ptr<T> type regardless of the deleter type, 
// deleter is stored in the "shared state" 
auto y = std::shared_ptr<T>(new T(...), deleter); 

Примечание, make_shared() не могут быть использованы для построения shared_ptr с пользовательскими Deleter.

Смежные вопросы