Я создал умный указатель класса, как:
template <class T>
class Owner
{
T* m_p;
public:
Owner(T *p=0) : m_p(p) {}
~Owner() { if (m_p) delete m_p; }
T* operator ->() { return m_p; }
T& operator *() { return *m_p; }
// other members.
};
Работает хорошо (напоминает auto_ptr
в Boost Library), но теперь у меня есть требования, которые я хочу хранить динамический массив интеллектуальных указателей в объекте, и он должен поддерживать:
1) вставьте новый умный указатель в массив умных указателей, чтобы размер массива изменился и он стал владельцем нового объекта,
2) удалить один умный указатель на лету, и ресурс освободится,
3) при финализации массива все объекты удаляются.
Я думал, используя std::vector<Owner<T> >
, но, похоже, лучшая практика c ++ предлагает не хранить умные указатели в контейнерах std, потому что это копирование / присваивание, так что же еще можно использовать для реализации этого? что-то вроде OwnerArr в следующем примере:
class Adapter;
class Computer
{
public:
Computer() {}
~Computer() { // adapters get freed automatically here. }
void insertAdapter(Adapter* pAdapter) { m_adapters->appendOne(pAdapter); }
OwnerArr<Adapter> m_adapters;
};
Заранее спасибо!
Вы не можете хранить свои Owner
, или же std::auto_ptr
(который вы не должны использовать в любом случае, поскольку он устарел), в стандартном контейнере, потому что они на самом деле не копируются.
В C ++ 11 есть std::unique_ptr
: умный указатель для одного владельца для замены auto_ptr
, который является подвижным, но не копируемым. Это может быть перемещено или помещено в любой контейнер, если вам не нужно делать что-либо, что включает в себя его копирование. Если вам нужно несколько указателей для совместного владения одним и тем же объектом, вы можете использовать std::shared_ptr
вместо.
Если по какой-то причине вы застряли на более старой языковой версии, Boost может дать вам умные указатели, в том числе shared_ptr
очень похож на стандартный, или контейнеры-указатели похож на ваш OwnerArray
,
Если вы решили применить свои собственные классы управления ресурсами, всегда помните Правило трех. Классы, которые вы показываете, имеют неявно сгенерированные конструкторы копирования и операторы копирования, которые могут заставить два указателя иметь — и пытаться удалить — один и тот же объект, что очень плохо. Вам необходимо либо предотвратить копирование (удалив эти функции, либо (до 2011 года) объявить их закрытыми без реализации), либо внедрить некоторую семантику безопасного копирования.
Других решений пока нет …