new[]
специально определено для того, чтобы иметь значение указателя, несмотря на неявное преобразование массива в указатель, которое в любом случае вылетело бы.
Но я не думаю, что тебе не повезло. В конце концов, ваш пример не управляет указателем на int
, он управляет указателем на int[10]
. Итак, идеальный способ это
MyAutoPtr<int[10]> ptr2(new int[10]);
Как упоминает Red-Nosed Unicorn, new int[10]
не создает массив в стиле C. Это будет, если ваш компилятор также соответствует стандарту C, но C ++ допускает, чтобы массивы в стиле C были больше, чем массивы в стиле C в C . В любом случае, new
создаст вам массив в стиле C, если вы спросите так:
MyAutoPtr<int[10]> ptr2(new int [1] [10]);
К сожалению, delete contents;
не будет работать даже с int (*contents)[10];
. Компилятору разрешено делать правильные вещи: стандарт не указывает, что массив преобразуется в указатель, как при new
, и я полагаю, что я помню GCC, подставив delete[]
и выдав предупреждение. Но это неопределенное поведение.
Итак, вам понадобятся два деструктора, один для вызова delete
и один для вызова delete[]
. Поскольку вы не можете частично специализировать функцию, функциональность требует частично специализированного помощника
template< class T > struct smartptr_dtor {
void operator()( T *ptr ) { delete ptr; }
};
template< class T, size_t N > struct smartptr_dtor< T[N] > {
void operator()( T (*ptr) [N] ) { delete [] ptr; }
};
template< class T >
void proper_delete( T *p ) {
smartptr_dtor< T >()( p );
}
, по какой-то причине я только что подвергся; v)
К сожалению, это не работает с массивами динамического размера, поэтому я собираюсь написать другой ответ.